package com.emm.yixun.website.controller.customer;

//框架包
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
import java.net.URLDecoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.emm.yixun.common.model.*;
import com.emm.yixun.common.model.dto.*;
import com.emm.yixun.common.model.enums.*;
import com.emm.yixun.common.page.PageUtil;
import com.emm.yixun.estate.service.ProjectPremisesServiceFacade;
import com.emm.yixun.marketing.service.HaveReceiveRefundServiceFacade;
import com.emm.yixun.system.service.*;
import org.activiti.engine.IdentityService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.emm.yixun.anotations.AvoidDuplicateSubmission;
import com.emm.yixun.anotations.MerchantResourcesConfig;
import com.emm.yixun.anotations.UserOperateLog;
import com.emm.yixun.common.enums.FunctionTypeEnum;
import com.emm.yixun.common.enums.ModelTypeEnum;
import com.emm.yixun.common.enums.ProcessTypeEnums;
import com.emm.yixun.common.model.BaseCodeValue;
import com.emm.yixun.common.model.BusinessAbnorma;
import com.emm.yixun.common.model.Customer;
import com.emm.yixun.common.model.FamilyMember;
import com.emm.yixun.common.model.NeedReceiveRefund;
import com.emm.yixun.common.model.PayDeposit;
import com.emm.yixun.common.model.PriceSchemeDetail;
import com.emm.yixun.common.model.Project;
import com.emm.yixun.common.model.ProjectRoom;
import com.emm.yixun.common.model.Signed;
import com.emm.yixun.common.model.SignedInfo;
import com.emm.yixun.common.model.Subscribe;
import com.emm.yixun.common.model.User;
import com.emm.yixun.common.model.dto.BaseCodeValueDto;
import com.emm.yixun.common.model.dto.BusinessAbnormaDto;
import com.emm.yixun.common.model.dto.FamilyMemberDto;
import com.emm.yixun.common.model.dto.HaveReceiveRefundDto;
import com.emm.yixun.common.model.dto.ImageDto;
import com.emm.yixun.common.model.dto.NeedReceiveRefundDto;
import com.emm.yixun.common.model.dto.ProjectRoomDto;
import com.emm.yixun.common.model.dto.SignedDto;
import com.emm.yixun.common.model.enums.AuditStatusEnum;
import com.emm.yixun.common.model.enums.BaseCodeTypeEnum;
import com.emm.yixun.common.model.enums.BusinessAbnormaEnum;
import com.emm.yixun.common.model.enums.BusinessTypeEnum;
import com.emm.yixun.common.model.enums.ContactTypeEnum;
import com.emm.yixun.common.model.enums.DealCategoryEnum;
import com.emm.yixun.common.model.enums.DecorationPaymentMethodEnum;
import com.emm.yixun.common.model.enums.DelFlagEnum;
import com.emm.yixun.common.model.enums.DocTypeEnum;
import com.emm.yixun.common.model.enums.FloorTypeEnum;
import com.emm.yixun.common.model.enums.MemberTypeEnum;
import com.emm.yixun.common.model.enums.MerchantEnum;
import com.emm.yixun.common.model.enums.PaymentMethodEnum;
import com.emm.yixun.common.model.enums.PropertyTypeEnum;
import com.emm.yixun.common.model.enums.ReceivablesTypeEnum;
import com.emm.yixun.common.model.enums.RoomStatusEnum;
import com.emm.yixun.common.page.Page;
import com.emm.yixun.common.response.Response;
import com.emm.yixun.common.response.ResponseList;
import com.emm.yixun.common.utils.BeanUtil;
import com.emm.yixun.common.utils.DateStyle;
import com.emm.yixun.common.utils.DateUtils;
import com.emm.yixun.customer.service.CustomerServiceFacade;
import com.emm.yixun.customer.service.FamilyMemberServiceFacade;
import com.emm.yixun.customer.service.PayDepositServiceFacade;
import com.emm.yixun.customer.service.SignedServiceFacade;
import com.emm.yixun.customer.service.SubscribeServiceFacade;
import com.emm.yixun.estate.service.ProjectRoomServiceFacade;
import com.emm.yixun.estate.service.ProjectServiceFacade;
import com.emm.yixun.marketing.service.BusinessAbnormaServiceFacade;
import com.emm.yixun.marketing.service.NeedReceiveRefundServiceFacade;
import com.emm.yixun.marketing.service.PriceSchemeDetailServiceFacade;
import com.emm.yixun.website.common.ajax.AjaxRes;
import com.emm.yixun.website.common.utils.base.Const;
import com.emm.yixun.website.common.utils.security.ShiroUtil;
import com.emm.yixun.website.controller.base.BaseController;
import com.emm.yixun.website.service.ActivitiProcessServiceImpl;
import com.emm.yixun.website.service.ao.DataService.OaDataService;
import com.emm.yixun.website.service.image.WsImageService;
import com.emm.yixun.website.service.marketing.HaveReceiveRefundService;
import com.emm.yixun.website.service.signed.SignedService;
import com.emm.yixun.website.utils.ExcelUtil;
import com.emm.yixun.website.utils.TokenProcessor;
import com.emm.yixun.website.vo.common.ExtResultVo;
import org.springframework.web.servlet.ModelAndView;
//common
//website
//变化的引用

@Controller
@RequestMapping("/customer/signed/")
public class SignedController extends BaseController<Signed> {

	@Autowired
	private SignedServiceFacade signedServiceFacade;
	@Autowired
	private SignedService signedService;
	@Autowired
	private ProjectRoomServiceFacade projectRoomServiceFacade;
	@Autowired
	private BusinessAbnormaServiceFacade businessAbnormaServiceFacade;
	@Autowired
	private CustomerServiceFacade customerServiceFacade;
	@Autowired
	private IdentityService identityService;
	@Autowired
	private UserServiceFacade userServiceFacade;
	@Autowired
	private PayDepositServiceFacade payDepositServiceFacade;
	@Autowired
	private SubscribeServiceFacade subscribeServiceFacade;
	@Autowired
	private HaveReceiveRefundService haveReceiveRefundService;
	@Autowired
	private FamilyMemberServiceFacade familyMemberServiceFacade;
	@Autowired
	private NeedReceiveRefundServiceFacade needReceiveRefundServiceFacade;
	@Autowired
	private ActivitiProcessServiceImpl activitiProcessService;
	@Autowired
	private BaseCodeValueServiceFacade baseCodeValueServiceFacade;
	@Autowired
	private MerchantServiceFacade merchantServiceFacade;
	@Autowired
	private ImageServiceFacade imageServiceFacade;
	@Autowired
	private WsImageService wsImageService;
	@Autowired
	private PriceSchemeDetailServiceFacade priceSchemeDetailServiceFacade;
	@Autowired
	private OaDataService oaDataService;
	@Autowired
	private ProjectServiceFacade projectServiceFacade;
	@Autowired
	private BusinessLogServiceFacade businessLogServiceFacade;
	@Autowired
	private HaveReceiveRefundServiceFacade haveReceiveRefundServiceFacade;

	@Autowired
	private ProjectPremisesServiceFacade  projectPremisesServiceFacade;

	@Autowired
	private NodeUserServiceFacade nodeUserServiceFacade;

	@RequestMapping(value = "index")
	public String index(ModelMap map) {
		if (doSecurityIntercept(Const.RESOURCES_TYPE_MENU)) {
			// 查询菜单按钮权限
			map.put("permitBtn", getPermitBtn(Const.RESOURCES_TYPE_FUNCTION));
			return "/customer/signed/list";
		}
		return Const.NO_AUTHORIZED_URL;
	}

	// 查看
	// marketing:signed:view
	@RequestMapping(value = "signedDetail", method = RequestMethod.POST)
	@ResponseBody
	public AjaxRes signedDetail(Long id) {
		AjaxRes ar = getAjaxRes();
		try {
			Response<Signed> response = signedServiceFacade.findById(id);
			if (response.isSuccess()) {
				ar.setSucceed(response.getEntity());
			} else {
				ar.setFailMsg(Const.DATA_FAIL);
			}
		} catch (Exception e) {
			logger.error(e.toString(), e);
			ar.setFailMsg(Const.DATA_FAIL);
		}
		return ar;
	}

	// marketing:signed:add
	@RequestMapping(value = "toAdd")
	@MerchantResourcesConfig(resourcesCode = "menu_0005_0004_0023")
	@AvoidDuplicateSubmission(needSaveToken = true)
	public String toAdd(ModelMap map, String roomId, String customerId, String payDepositId, String subscribeId,
			HttpServletRequest request, HttpServletResponse resp, String returnUrl, String isChooseCustomer) {
		if (doSecurityIntercept(Const.RESOURCES_TYPE_BUTTON, "marketing:signed:add")) {
			Boolean showChooseCustomer = Boolean.FALSE;
			User user = ShiroUtil.getCurrentUser();
			// 认筹开关,默认未关闭(false) ,true已关闭
			boolean payDepositOff = false;
			Response<Boolean> response2 = merchantServiceFacade.merPayDepositOff(user.getMerchantId());
			if (response2.isSuccess()) {
				payDepositOff = response2.getEntity();
			}
			// 查询菜单按钮权限
			map.put("permitBtn", getPermissionBtnArray());
			map.put("userId", user.getId());
			String typeName = BaseCodeTypeEnum.getByNo(BaseCodeTypeEnum.TYPE_TWELVE.getNo()).getDes();
			BaseCodeValueDto bcvDto = new BaseCodeValueDto();
			bcvDto.setMerchantId(user.getMerchantId());
			bcvDto.setProjectId(Long.parseLong(request.getParameter("projectId")));
			bcvDto.setTypeName(typeName);
			bcvDto.setDelFlag(DelFlagEnum.UNDEL.getNo());
			// *1解决数字排序问题.例如 1,2,10.排序后会显示成 1,10,2
			bcvDto.setOrders("t.sort*1");
			JSONArray dtArray = JSONArray.parseArray(baseCodeValueServiceFacade.getBcvJsonArray(bcvDto));

			map.put("documentType", dtArray.toJSONString());

			JSONArray pmArray = new JSONArray();
			for (PaymentMethodEnum dt : PaymentMethodEnum.values()) {
				JSONObject row = new JSONObject();
				row.put("value", dt.getNo());
				row.put("name", dt.getDes());
				pmArray.add(row);
			}
			map.put("paymentMethods", pmArray.toJSONString());

			JSONArray ctArray = new JSONArray();
			for (ContactTypeEnum dt : ContactTypeEnum.values()) {
				JSONObject row = new JSONObject();
				row.put("value", dt.getNo());
				row.put("name", dt.getDes());
				ctArray.add(row);
			}
			map.put("contactTypes", ctArray.toJSONString());

			map.put("currentUserName", user.getUserName());
			map.put("payDeposit", new PayDeposit());
			if (StringUtils.isNotBlank(payDepositId)) {
				Response<PayDeposit> response = payDepositServiceFacade.findById(Long.valueOf(payDepositId));
				if (response.isSuccess() && null != response.getEntity()) {
					PayDeposit payDeposit = response.getEntity();
					map.put("payDeposit", payDeposit);
					map.put("signedContractAmount", net.sf.json.JSONArray
							.fromObject(signedServiceFacade.signedContractAmount(payDeposit.getId(), null)));
				}

			}

			if (StringUtils.isNotBlank(subscribeId)) {
				Response<Subscribe> response = subscribeServiceFacade.findById(Long.valueOf(subscribeId));
				if (response.isSuccess() && null != response.getEntity()) {
					Subscribe subscribe = response.getEntity();
					/*
					 * if (null != subscribe.getCustomerId()) customerId =
					 * String.valueOf(subscribe.getCustomerId()); if (null != subscribe.getRoomId())
					 * roomId = String.valueOf(subscribe.getRoomId());
					 */
					HaveReceiveRefundDto entity = new HaveReceiveRefundDto();
					entity.setDocType("0");
					entity.setReceivablesType("1");
					entity.setRelationId(Long.valueOf(subscribeId));
					Double amount = haveReceiveRefundService.getRealAmount(entity);
					subscribe.setDepositReceivable(new BigDecimal(amount));
					map.put("subscribe", subscribe);
					map.put("signedContractAmount", net.sf.json.JSONArray
							.fromObject(signedServiceFacade.signedContractAmount(null, subscribe.getId())));
				}
			} else {
				map.put("subscribe", new Subscribe());
			}
			if (!StringUtils.isBlank(customerId)) {
				map.put("signedContractAmount",
						net.sf.json.JSONArray.fromObject(signedServiceFacade.signedContractAmount(null, null)));
				map.put("customerId", customerId);
				Response<Customer> customerResponse = customerServiceFacade.findById(Long.valueOf(customerId));
				if (customerResponse.isSuccess() && null != customerResponse.getEntity()) {
					map.put("customerProjectId", customerResponse.getEntity().getProjectId());
				}
			}
			if (!StringUtils.isBlank(roomId)) {
				map.put("signedContractAmount",
						net.sf.json.JSONArray.fromObject(signedServiceFacade.signedContractAmount(null, null)));
				map.put("roomId", roomId);
			}
			/*
			 * map.put("payDepositId", StringUtils.isBlank(payDepositId) ? "" :
			 * payDepositId); map.put("subscribeId", StringUtils.isBlank(subscribeId) ? "" :
			 * subscribeId);
			 */
			map.put("menu", request.getParameter("menu"));
			if (!com.alibaba.druid.util.StringUtils.isEmpty(returnUrl)) {
				map.put("returnUrl", returnUrl.replace(",", "/").replace("(", "?").replace(")", "="));
			}
			// url
			map.put("url", request.getServletPath() + "?" + request.getQueryString());

			map.put("projectId", request.getParameter("projectId"));
			map.put("payDepositOff", payDepositOff);
			if (StringUtils.isNotBlank(isChooseCustomer))
				showChooseCustomer = Boolean.TRUE;
			map.put("showChooseCustomer", showChooseCustomer);
			return "/customer/signed/add";
		}
		return Const.NO_AUTHORIZED_URL;
	}

	/**
	 * 绿城定制 不满足意向等级的用户需完善客户信息才能签约（页面做判断）
	 * 
	 * @param map
	 * @param roomId
	 * @param customerId
	 * @param payDepositId
	 * @param subscribeId
	 * @param request
	 * @param returnUrl
	 * @param isChooseCustomer
	 * @return
	 */
	@RequestMapping(value = "toAddLC")
	@AvoidDuplicateSubmission(needSaveToken = true)
	public String toAddLC(ModelMap map, String roomId, String customerId, String payDepositId, String subscribeId,
			HttpServletRequest request, String returnUrl, String isChooseCustomer) {
		if (doSecurityIntercept(Const.RESOURCES_TYPE_BUTTON, "marketing:signed:add")) {
			Boolean showChooseCustomer = Boolean.FALSE;
			User user = ShiroUtil.getCurrentUser();
			// 认筹开关,默认未关闭(false) ,true已关闭
			boolean payDepositOff = false;
			Response<Boolean> response2 = merchantServiceFacade.merPayDepositOff(user.getMerchantId());
			if (response2.isSuccess()) {
				payDepositOff = response2.getEntity();
			}
			// 查询菜单按钮权限
			map.put("permitBtn", getPermissionBtnArray());
			map.put("userId", user.getId());
			String typeName = BaseCodeTypeEnum.getByNo(BaseCodeTypeEnum.TYPE_TWELVE.getNo()).getDes();
			BaseCodeValueDto bcvDto = new BaseCodeValueDto();
			bcvDto.setMerchantId(user.getMerchantId());
			bcvDto.setTypeName(typeName);
			bcvDto.setProjectId(Long.parseLong(request.getParameter("projectId")));
			bcvDto.setDelFlag(DelFlagEnum.UNDEL.getNo());
			// *1解决数字排序问题.例如 1,2,10.排序后会显示成 1,10,2
			bcvDto.setOrders("t.sort*1");
			JSONArray dtArray = JSONArray.parseArray(baseCodeValueServiceFacade.getBcvJsonArray(bcvDto));
			map.put("documentType", dtArray.toJSONString());

			JSONArray pmArray = new JSONArray();
			for (PaymentMethodEnum dt : PaymentMethodEnum.values()) {
				JSONObject row = new JSONObject();
				row.put("value", dt.getNo());
				row.put("name", dt.getDes());
				pmArray.add(row);
			}
			map.put("paymentMethods", pmArray.toJSONString());

			JSONArray ctArray = new JSONArray();
			for (ContactTypeEnum dt : ContactTypeEnum.values()) {
				JSONObject row = new JSONObject();
				row.put("value", dt.getNo());
				row.put("name", dt.getDes());
				ctArray.add(row);
			}
			map.put("contactTypes", ctArray.toJSONString());

			map.put("currentUserName", user.getUserName());
			map.put("payDeposit", new PayDeposit());
			if (StringUtils.isNotBlank(payDepositId)) {
				Response<PayDeposit> response = payDepositServiceFacade.findById(Long.valueOf(payDepositId));
				if (response.isSuccess() && null != response.getEntity()) {
					PayDeposit payDeposit = response.getEntity();
					map.put("payDeposit", payDeposit);
					map.put("signedContractAmount", net.sf.json.JSONArray
							.fromObject(signedServiceFacade.signedContractAmount(payDeposit.getId(), null)));
				}

			}

			if (StringUtils.isNotBlank(subscribeId)) {
				Response<Subscribe> response = subscribeServiceFacade.findById(Long.valueOf(subscribeId));
				if (response.isSuccess() && null != response.getEntity()) {
					Subscribe subscribe = response.getEntity();
					/*
					 * if (null != subscribe.getCustomerId()) customerId =
					 * String.valueOf(subscribe.getCustomerId()); if (null != subscribe.getRoomId())
					 * roomId = String.valueOf(subscribe.getRoomId());
					 */
					HaveReceiveRefundDto entity = new HaveReceiveRefundDto();
					entity.setDocType("0");
					entity.setReceivablesType("1");
					entity.setRelationId(Long.valueOf(subscribeId));
					Double amount = haveReceiveRefundService.getRealAmount(entity);
					subscribe.setDepositReceivable(new BigDecimal(amount));
					map.put("subscribe", subscribe);
					map.put("signedContractAmount", net.sf.json.JSONArray
							.fromObject(signedServiceFacade.signedContractAmount(null, subscribe.getId())));
				}
			} else {
				map.put("subscribe", new Subscribe());
			}
			if (!StringUtils.isBlank(customerId)) {
				map.put("signedContractAmount",
						net.sf.json.JSONArray.fromObject(signedServiceFacade.signedContractAmount(null, null)));
				map.put("customerId", customerId);
				Response<Customer> customerResponse = customerServiceFacade.findById(Long.valueOf(customerId));
				if (customerResponse.isSuccess() && null != customerResponse.getEntity()) {
					map.put("customerProjectId", customerResponse.getEntity().getProjectId());
				}
			}
			if (!StringUtils.isBlank(roomId)) {
				map.put("signedContractAmount",
						net.sf.json.JSONArray.fromObject(signedServiceFacade.signedContractAmount(null, null)));
				map.put("roomId", roomId);
			}
			/*
			 * map.put("payDepositId", StringUtils.isBlank(payDepositId) ? "" :
			 * payDepositId); map.put("subscribeId", StringUtils.isBlank(subscribeId) ? "" :
			 * subscribeId);
			 */
			map.put("menu", request.getParameter("menu"));
			if (!com.alibaba.druid.util.StringUtils.isEmpty(returnUrl)) {
				map.put("returnUrl", returnUrl.replace(",", "/").replace("(", "?").replace(")", "="));
			}
			// url
			map.put("url", request.getServletPath() + "?" + request.getQueryString());

			map.put("projectId", request.getParameter("projectId"));
			map.put("payDepositOff", payDepositOff);
			if (StringUtils.isNotBlank(isChooseCustomer))
				showChooseCustomer = Boolean.TRUE;
			map.put("showChooseCustomer", showChooseCustomer);
			return "/customer/signed/addLC";
		}
		return Const.NO_AUTHORIZED_URL;
	}

	// 新增返回实体对象
	@RequestMapping(value = "add", method = RequestMethod.POST)
	@ResponseBody
	@UserOperateLog(functionName = FunctionTypeEnum.FUNCTIONTYPE_5, modelName = ModelTypeEnum.MODELTYPE_2, roomKey = "roomId")
	@AvoidDuplicateSubmission(needRemoveToken = true)
	public AjaxRes add(String params, Boolean startProcess, HttpServletRequest request) {
		AjaxRes ar = getAjaxRes();
		// 操作失败时,重新刷新提交Token
		String newToken = TokenProcessor.getInstance().generateToken(request);
		request.getSession(false).setAttribute("token", newToken);
		/*
		 * 1.判断权限2.调用新增接口3.返回信息
		 */
		User user = ShiroUtil.getCurrentUser();
		if (ar.setNoAuth(doSecurityIntercept(Const.RESOURCES_TYPE_BUTTON, "marketing:signed:add"))) {
			try {
				SignedDto paramsSignedDto = JSONObject.parseObject(params, SignedDto.class);
				Response<ProjectRoom> projectRoomResponse = projectRoomServiceFacade
						.findById(paramsSignedDto.getRoomId());
				Long projectId = projectRoomResponse.getEntity().getProjectId();
				if (null == projectId) {
					ar.setFailMsg("项目不存在!");
					ar.setObj(newToken);
					return ar;
				}
				String signedStartProcessKey = "";
				String signedDiscountStartProcessKey = "";
				if (startProcess) {
					// 动态获取签约审批KEY
					signedStartProcessKey = activitiProcessService.getProcessKey(user.getMerchantId(), projectId,
							ProcessTypeEnums.PROCESS_KEY_12);
					if (StringUtils.isEmpty(signedStartProcessKey)) {
						ar.setFailMsg("项目未设置签约审批流程,请去项目流程菜单配置！");
						ar.setObj(newToken);
						return ar;
					}
					// 动态获取签约折扣审批流程KEY
					signedDiscountStartProcessKey = activitiProcessService.getProcessKey(user.getMerchantId(),
							projectId, ProcessTypeEnums.PROCESS_KEY_13);
					if (StringUtils.isEmpty(signedDiscountStartProcessKey)) {
						ar.setFailMsg("项目未设置签约折扣审批流程,请去项目流程菜单配置！");
						ar.setObj(newToken);
						return ar;
					}
					boolean isSeting = activitiProcessService.checkNodeUser(user.getMerchantId(), projectId,
							signedStartProcessKey);
					if (!isSeting) {
						ar.setFailMsg("签约审批流程节点人员未设置");
						ar.setObj(newToken);
						return ar;
					}
					isSeting = activitiProcessService.checkNodeUser(user.getMerchantId(), projectId,
							signedDiscountStartProcessKey);
					if (!isSeting) {
						ar.setFailMsg("签约折扣审批流程节点人员未设置");
						ar.setObj(newToken);
						return ar;
					}
				}
				boolean startFlag = true;
				String resMsg = "签约成功";
				Response<SignedDto> response = signedServiceFacade.addSigned(params, user);
				SignedDto signedDto = response.getEntity();
				if (response.isSuccess()) {
					String pid = null;
					if (startProcess) {
						Map<String, Object> variables = new HashMap<String, Object>();
						identityService.setAuthenticatedUserId(user.getUserAccount());
						/* String discountApproval = signedDto.getDiscountApproval(); */
						String processKey = "";
						Response<PriceSchemeDetail> priceDetail = priceSchemeDetailServiceFacade
								.selectEntityByRoomId(paramsSignedDto.getRoomId());
						if (priceDetail.getEntity() != null) {
							PriceSchemeDetail detail = priceDetail.getEntity();
							if (null == detail.getDiscountRate()) {
								// 房源对应的价格方案,无折后总价或折扣比例
								startFlag = true;
							} else {
								// 价格方案是折扣的时候
								if (paramsSignedDto.getFloorType().equals(FloorTypeEnum.DISCOUNT_RATE.getNo())) {
									if (paramsSignedDto.getDiscountRate() == null) {
										paramsSignedDto.setDiscountRate(new BigDecimal(new BigInteger("100")));
									}
									// 绿城,根据价格方案的设置,计算是否要发起折扣审批
									if (MerchantEnum.FENGCE.getNo().equals(String.valueOf(user.getMerchantId()))) {
										// paramsSignedDto.getDiscountRate(): 签约中的实际折扣比例
										double discountDiff = 100 - Double.valueOf(String.valueOf(paramsSignedDto.getDiscountRate()));
										variables.put("signDiscountRate", discountDiff);
										if (discountDiff >= 1) {
											startFlag = false;
										}
									} else {
										if (detail.getDiscountRate().compareTo(paramsSignedDto.getDiscountRate()) > 0) { // 需要发起折扣审批
											startFlag = false;
										}
									}
								} else if (paramsSignedDto.getFloorType()
										.equals(FloorTypeEnum.DISCOUNT_AMOUNT.getNo())) {
									if (paramsSignedDto.getDiscountAfterPrice() == null) {
										paramsSignedDto.setDiscountAfterPrice(paramsSignedDto.getSignAmount());
									}
									if (detail.getDiscountRate()
											.compareTo(paramsSignedDto.getDiscountAfterPrice()) > 0) {
										startFlag = false;
									}
								}
							}
						}
						if (startFlag) {
							// 不需要折扣审批
							processKey = signedStartProcessKey;
							pid = activitiProcessService.startProcessInstance(user.getMerchantId(), projectId,
									processKey, signedDto.getId().toString(), variables);
							SignedDto updateSignedDto = new SignedDto();
							updateSignedDto.setId(signedDto.getId());
							updateSignedDto.setAuditStatus(AuditStatusEnum.AUDIT.getNo());
							updateSignedDto.setProcInstId(pid);
							updateSignedDto.setCheckDate(new Date());
							signedServiceFacade.updateByPrimaryKey(updateSignedDto, true);
						} else {
							// 需要折扣审批
							processKey = signedDiscountStartProcessKey;
							pid = activitiProcessService.startProcessInstance(user.getMerchantId(), projectId,
									processKey, signedDto.getId().toString(), variables);
							BusinessAbnormaDto queryDto = new BusinessAbnormaDto();
							queryDto.setBusinessId(signedDto.getId());
							queryDto.setBusinessType("2");
							ResponseList<BusinessAbnorma> responseList = businessAbnormaServiceFacade
									.findByDto(queryDto);
							if (null != responseList && null != responseList.getEntity()
									&& responseList.getEntity().size() > 0) {
								BusinessAbnorma businessAbnorma = responseList.getEntity().get(0);
								BusinessAbnormaDto updateBADto = new BusinessAbnormaDto();
								updateBADto.setId(businessAbnorma.getId());
								updateBADto.setProcInstId(pid);
								updateBADto.setAuditStatus(AuditStatusEnum.AUDIT.getNo());
								updateBADto.setCheckDate(new Date());
								businessAbnormaServiceFacade.updateByPrimaryKey(updateBADto, true);
							}
							// 需要折扣审批也
							SignedDto updateSignedDto = new SignedDto();
							updateSignedDto.setId(signedDto.getId());
							updateSignedDto.setAuditStatus(AuditStatusEnum.AUDIT.getNo());
							updateSignedDto.setProcInstId(pid);
							signedServiceFacade.updateByPrimaryKey(updateSignedDto, true);
						}
						// 修改房源状态为认筹
						ProjectRoomDto projectRoomDto = new ProjectRoomDto();
						projectRoomDto.setId(signedDto.getRoomId());
						projectRoomDto.setRoomStatus(RoomStatusEnum.SIGN.getNo());
						projectRoomServiceFacade.updateByPrimaryKey(projectRoomDto, true);

						// 创建并发送提醒消息
						if (pid != null) {
							signedDto.setProcInstId(pid);
						}

						// 保存流程附件
						JSONObject paramsObject = JSONObject.parseObject(params);
						String fileUrlArr = paramsObject.getString("fileUrlArr");
						String imageType = paramsObject.getString("imageType");
						wsImageService.uploadAttachment(fileUrlArr, String.valueOf(signedDto.getId()), imageType,
								signedDto.getAccessCode());
					} else {
						// 添加流程审核需要的图片
						JSONObject paramsObject = JSONObject.parseObject(params);
						String fileUrlArr = paramsObject.getString("fileUrlArr");
						String imageType = paramsObject.getString("imageType");
						wsImageService.uploadAttachment(fileUrlArr, String.valueOf(signedDto.getId()), imageType,
								signedDto.getAccessCode());
						resMsg = "签约保存成功";
					}
					ar.setObj(response.getEntity().getId());
					ar.setRes(Const.SUCCEED);
					ar.setResMsg(resMsg);
				} else {
					ar.setFailMsg(response.getResultMessage());
				}
			} catch (Exception ex) {
				//新增业务操作异常记录
				businessLogServiceFacade.saveExceptionLog(user, "新增签约", params, JSONObject.toJSONString(ex));
				
				logger.error("签约失败", ex);
				ar.setFailMsg(Const.SAVE_FAIL);
			}
		}
		// 失败,返回新的Token.
		if (Const.FAIL == ar.getRes()) {
			ar.setObj(newToken);
		}
		return ar;
	}

	public void saveProcessFile(String projectCode, String pid, String[] fileArr) {
		if (null == fileArr || fileArr.length == 0 || StringUtils.isBlank(pid) || StringUtils.isBlank(projectCode))
			return;
		User user = ShiroUtil.getCurrentUser();
		for (int ii = 0; ii < fileArr.length; ii++) {
			if (StringUtils.isNotEmpty(fileArr[ii])) {
				try {
					ImageDto imageDto = new ImageDto();
					imageDto.setObjectId(Long.valueOf(pid));
					imageDto.setTitle("流程附件");
					imageDto.setContent("流程附件");
					imageDto.setSmallUrl(fileArr[ii]);
					imageDto.setImgType("6");
					imageDto.setMerchantId(user.getMerchantId());
					imageDto.setUserCode(user.getUserCode());
					imageDto.setAccessCode(projectCode);
					imageDto.setCreateUserId(user.getId());
					imageDto.setDelFlag(DelFlagEnum.UNDEL.getNo());
					imageServiceFacade.save(imageDto);
				} catch (NumberFormatException e) {
					e.printStackTrace();
				}
			}
		}
	}

	@RequestMapping(value = "toPrint")
	public ModelAndView toPrint(ModelMap map, Long id, String procInstId, String processFlag, String process,
								HttpServletRequest request, String returnUrl) {
		ModelAndView mv = new ModelAndView("/customer/signed/signedPrint");

		Response<Signed> signedResponse = signedServiceFacade.findById(id);
		Signed signed = signedResponse.getEntity();
		mv.addObject("calculateArea",signed.getCalculateArea());
		mv.addObject("signPrice",signed.getSignPrice());
		mv.addObject("signAmount",signed.getSignAmount());

		String paymentMethod = PaymentMethodEnum.getByNo(signed.getPaymentMethod()).getDes();
		paymentMethod = "2".equals(signed.getDecorationPaymentMethod()) ? "首付分期【" + paymentMethod + "】" : paymentMethod;
		mv.addObject("paymentMethod", paymentMethod);
		mv.addObject("checkDate",DateUtils.DateToString(signed.getCheckDate(), DateUtils.parsePatterns[1]));

		if(signed.getSubscribeId()!=null) {
			Response<Subscribe> subscribeResponse = subscribeServiceFacade.findById(signed.getSubscribeId());
			Subscribe subscribe = subscribeResponse.getEntity();
			mv.addObject("subscribeCheckDate", DateUtils.DateToString(subscribe.getCheckDate(), DateUtils.parsePatterns[1]));
		}

		HaveReceiveRefundDto hrrfDto = new HaveReceiveRefundDto();
		hrrfDto.setRelationId(signed.getId());
		hrrfDto.setReceivablesType(ReceivablesTypeEnum.SIGNED.getNo());
		hrrfDto.setDocType(DocTypeEnum.COLLECTION.getNo());
		double info_signedReceived = haveReceiveRefundServiceFacade.haveReceiveAmount(hrrfDto);
		mv.addObject("depositReceivable", new BigDecimal(info_signedReceived).setScale(2));

		NeedReceiveRefundDto nrrDto = new NeedReceiveRefundDto();
		nrrDto.setRelationId(signed.getId());
		nrrDto.setBusinessType(BusinessTypeEnum.SIGNED.getNo());
		nrrDto.setDocType(DocTypeEnum.COLLECTION.getNo());
		ResponseList<NeedReceiveRefund> needReceiveRefundResponseList = needReceiveRefundServiceFacade.findByDto(nrrDto);

		BigDecimal receivableAmount = new BigDecimal(0);
		BigDecimal firstRate = new BigDecimal(0);
		BigDecimal surplusRate = new BigDecimal(0);
		switch (signed.getPaymentMethod()){
			case "1" :
				for(NeedReceiveRefund needReceiveRefund : needReceiveRefundResponseList.getEntity()){
					if(HousingFundTypeEnum.FUNDTYPE_5.getNo().equals(needReceiveRefund.getHousingFundType())
							||HousingFundTypeEnum.getByNo(needReceiveRefund.getHousingFundType()).getDes().indexOf("首付")>-1) {
						receivableAmount = receivableAmount.add(needReceiveRefund.getTotalReceivablesAmount());
					}
				}
				firstRate = receivableAmount.divide(signed.getSignAmount(), 2, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
				mv.addObject("receivableAmount", receivableAmount);
				mv.addObject("firstRate",firstRate.toString()+"%");
				break;
			case "2" :
				for(NeedReceiveRefund needReceiveRefund : needReceiveRefundResponseList.getEntity()){
					if(HousingFundTypeEnum.FUNDTYPE_12.getNo().equals(needReceiveRefund.getHousingFundType())
							||HousingFundTypeEnum.getByNo(needReceiveRefund.getHousingFundType()).getDes().indexOf("首付")>-1) {
						receivableAmount = receivableAmount.add(needReceiveRefund.getTotalReceivablesAmount());
					}
				}
				firstRate = receivableAmount.divide(signed.getSignAmount(), 2, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
				mv.addObject("receivableAmount", receivableAmount);
				mv.addObject("firstRate",firstRate.toString()+"%");
				surplusRate = new BigDecimal(100).subtract(firstRate);
				mv.addObject("surplusRate",surplusRate.toString()+"%");
				mv.addObject("surplusAmount",signed.getSignAmount().subtract(receivableAmount));
				break;
			case "3" :
				for(NeedReceiveRefund needReceiveRefund : needReceiveRefundResponseList.getEntity()){
					if(HousingFundTypeEnum.FUNDTYPE_6.getNo().equals(needReceiveRefund.getHousingFundType())
							||HousingFundTypeEnum.getByNo(needReceiveRefund.getHousingFundType()).getDes().indexOf("首付")>-1) {
						receivableAmount = receivableAmount.add(needReceiveRefund.getTotalReceivablesAmount());
					}else if(HousingFundTypeEnum.FUNDTYPE_7.getNo().equals(needReceiveRefund.getHousingFundType())){
						mv.addObject("orgName",needReceiveRefund.getOrgName());
						surplusRate = needReceiveRefund.getTotalReceivablesAmount().divide(signed.getSignAmount(), 2, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
						mv.addObject("surplusRate",surplusRate.toString()+"%");
						mv.addObject("surplusAmount",needReceiveRefund.getTotalReceivablesAmount());
					}
				}
				firstRate = receivableAmount.divide(signed.getSignAmount(), 2, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
				mv.addObject("receivableAmount",receivableAmount);
				mv.addObject("firstRate",firstRate.toString()+"%");
				break;
			case "4" :
				for(NeedReceiveRefund needReceiveRefund : needReceiveRefundResponseList.getEntity()){
					if(HousingFundTypeEnum.FUNDTYPE_10.getNo().equals(needReceiveRefund.getHousingFundType())
							||HousingFundTypeEnum.getByNo(needReceiveRefund.getHousingFundType()).getDes().indexOf("首付")>-1) {
						receivableAmount = receivableAmount.add(needReceiveRefund.getTotalReceivablesAmount());
					}else if(HousingFundTypeEnum.FUNDTYPE_11.getNo().equals(needReceiveRefund.getHousingFundType())){
						mv.addObject("orgName",needReceiveRefund.getOrgName());
						surplusRate = needReceiveRefund.getTotalReceivablesAmount().divide(signed.getSignAmount(), 2, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
						mv.addObject("surplusRate",surplusRate.toString()+"%");
						mv.addObject("surplusAmount",needReceiveRefund.getTotalReceivablesAmount());
					}
				}
				firstRate = receivableAmount.divide(signed.getSignAmount(), 2, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
				mv.addObject("receivableAmount",receivableAmount);
				mv.addObject("firstRate",firstRate.toString()+"%");
				break;
			case "5" :
				for(NeedReceiveRefund needReceiveRefund : needReceiveRefundResponseList.getEntity()){
					if(HousingFundTypeEnum.FUNDTYPE_17.getNo().equals(needReceiveRefund.getHousingFundType())
							||HousingFundTypeEnum.getByNo(needReceiveRefund.getHousingFundType()).getDes().indexOf("首付")>-1) {
						receivableAmount = receivableAmount.add(needReceiveRefund.getTotalReceivablesAmount());
					}else if(HousingFundTypeEnum.FUNDTYPE_18.getNo().equals(needReceiveRefund.getHousingFundType())){
						mv.addObject("orgName",needReceiveRefund.getOrgName());
					}
				}
				firstRate = receivableAmount.divide(signed.getSignAmount(), 2, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
				mv.addObject("receivableAmount",receivableAmount);
				mv.addObject("firstRate",firstRate.toString()+"%");
				surplusRate = new BigDecimal(100).subtract(firstRate);
				mv.addObject("surplusRate",surplusRate.toString()+"%");
				mv.addObject("surplusAmount",signed.getSignAmount().subtract(receivableAmount));
				break;
			case "6" :
				for(NeedReceiveRefund needReceiveRefund : needReceiveRefundResponseList.getEntity()){
					if(HousingFundTypeEnum.FUNDTYPE_43.getNo().equals(needReceiveRefund.getHousingFundType())
							||HousingFundTypeEnum.getByNo(needReceiveRefund.getHousingFundType()).getDes().indexOf("首付")>-1) {
						receivableAmount = receivableAmount.add(needReceiveRefund.getTotalReceivablesAmount());
					}
				}
				firstRate = receivableAmount.divide(signed.getSignAmount(), 2, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
				mv.addObject("receivableAmount", receivableAmount);
				mv.addObject("firstRate",firstRate.toString()+"%");
				break;
			case "7" :
				for(NeedReceiveRefund needReceiveRefund : needReceiveRefundResponseList.getEntity()){
					if(HousingFundTypeEnum.FUNDTYPE_35.getNo().equals(needReceiveRefund.getHousingFundType())
							||HousingFundTypeEnum.getByNo(needReceiveRefund.getHousingFundType()).getDes().indexOf("分期")>-1) {
						receivableAmount = receivableAmount.add(needReceiveRefund.getTotalReceivablesAmount());
					}
				}
				firstRate = receivableAmount.divide(signed.getSignAmount(), 2, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
				mv.addObject("receivableAmount", receivableAmount);
				mv.addObject("firstRate",firstRate.toString()+"%");
				break;
			case "8" :
				for(NeedReceiveRefund needReceiveRefund : needReceiveRefundResponseList.getEntity()){
					if(HousingFundTypeEnum.FUNDTYPE_35.getNo().equals(needReceiveRefund.getHousingFundType())
							||HousingFundTypeEnum.getByNo(needReceiveRefund.getHousingFundType()).getDes().indexOf("分期")>-1) {
						receivableAmount = receivableAmount.add(needReceiveRefund.getTotalReceivablesAmount());
					}else if(HousingFundTypeEnum.FUNDTYPE_36.getNo().equals(needReceiveRefund.getHousingFundType())){
						mv.addObject("orgName",needReceiveRefund.getOrgName());
						surplusRate = needReceiveRefund.getTotalReceivablesAmount().divide(signed.getSignAmount(), 2, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
						mv.addObject("surplusRate",surplusRate.toString()+"%");
						mv.addObject("surplusAmount",needReceiveRefund.getTotalReceivablesAmount());
					}
				}
				firstRate = receivableAmount.divide(signed.getSignAmount(), 2, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
				mv.addObject("receivableAmount",receivableAmount);
				mv.addObject("firstRate",firstRate.toString()+"%");
				break;
		}

		FamilyMemberDto fmd = new FamilyMemberDto();
		fmd.setMemberType("4");
		fmd.setBuyId(id);
		ResponseList<FamilyMember> familyMemberResponseList = familyMemberServiceFacade.findByDto(fmd);
		if (familyMemberResponseList.isSuccess() && familyMemberResponseList.getEntity() != null && familyMemberResponseList.getEntity().size() > 0) {
			mv.addObject("familyCustomerName",familyMemberResponseList.getEntity().get(0).getMemberName());
			mv.addObject("familyCustomerPhone",familyMemberResponseList.getEntity().get(0).getMobile());
			mv.addObject("familyPeDocumentNumber",familyMemberResponseList.getEntity().get(0).getDocumentNumber());
		}

		UserDto userDto = new UserDto();
		userDto.setUserCode(signed.getUserCode());
		ResponseList<User> userResponseList = userServiceFacade.findByDto(userDto);
		if(userResponseList.getEntity()!=null){
			mv.addObject("userName",userResponseList.getEntity().get(0).getUserName());
		}

		Response<Customer> customerResponse = customerServiceFacade.findById(signed.getCustomerId());
		mv.addObject("customerName",customerResponse.getEntity().getCustomerName());
		mv.addObject("customerPhone",customerResponse.getEntity().getCustomerPhone());
		mv.addObject("peDocumentNumber",customerResponse.getEntity().getPeDocumentNumber());
		mv.addObject("peContactAddress",customerResponse.getEntity().getPeContactAddress());

		Response<ProjectRoom> roomResponse = projectRoomServiceFacade.findById(signed.getRoomId());
		String[] combinedName = roomResponse.getEntity().getCombinedName().split("-->");
		StringBuffer roomName = new StringBuffer();
		for (int i=0; i<combinedName.length; i++) {
			if(StringUtils.isNotBlank(combinedName[i])){
				roomName.append(combinedName[i]).append("-");
			}
		}
		roomName.deleteCharAt(roomName.length()-1);
		mv.addObject("roomName",roomName);
		return mv;
	}

	// marketing:signed:view
	@RequestMapping(value = "toView")
	public String toView(ModelMap map, Long id, String procInstId, String processFlag, String process,
			HttpServletRequest request, String returnUrl) {
		User user = ShiroUtil.getCurrentUser();
		// 认筹开关,默认未关闭(false) ,true已关闭
		boolean payDepositOff = false;
		Response<Boolean> response2 = merchantServiceFacade.merPayDepositOff(user.getMerchantId());
		if (response2.isSuccess()) {
			payDepositOff = response2.getEntity();
		}
		String typeName = BaseCodeTypeEnum.getByNo(BaseCodeTypeEnum.TYPE_TWELVE.getNo()).getDes();
		BaseCodeValueDto bcvDto = new BaseCodeValueDto();
		bcvDto.setMerchantId(user.getMerchantId());
		bcvDto.setTypeName(typeName);
		bcvDto.setDelFlag(DelFlagEnum.UNDEL.getNo());
		bcvDto.setProjectId(153l);
		// *1解决数字排序问题.例如 1,2,10.排序后会显示成 1,10,2
		bcvDto.setOrders("t.sort*1");
		JSONArray dtArray = JSONArray.parseArray(baseCodeValueServiceFacade.getBcvJsonArray(bcvDto));
		JSONArray pmArray = new JSONArray();
		for (PaymentMethodEnum dt : PaymentMethodEnum.values()) {
			JSONObject row = new JSONObject();
			row.put("value", dt.getNo());
			row.put("name", dt.getDes());
			pmArray.add(row);
		}
		map.put("paymentMethods", pmArray.toJSONString());

		JSONArray ctArray = new JSONArray();
		for (ContactTypeEnum dt : ContactTypeEnum.values()) {
			JSONObject row = new JSONObject();
			row.put("value", dt.getNo());
			row.put("name", dt.getDes());
			ctArray.add(row);
		}
		map.put("contactTypes", ctArray.toJSONString());
		Response<SignedInfo> response = signedServiceFacade.findByIdInfo(id);
		String shouStatus = null;
		if (response.isSuccess()) {
			SignedInfo signed = response.getEntity();
			String nodeName = nodeUserServiceFacade.selectNodeUserName(response.getEntity().getProcInstId());
			if(nodeName != null && nodeName != ""){
				nodeName = nodeName.replace(",","->");
				map.put("nodeName","审批人->"+nodeName);
				signed.setNodeName("审批人->"+nodeName);
			}

			Long signedId = signed.getId();
			if (signed.getOldSignedId() != null) {
				// 当签约记录为换房签约时，获取原签约Id
				signedId = signed.getOldSignedId();
				map.addAttribute("oldSignedId", signedId);
			}
			map.addAttribute("businessSecStatus", signed.getBusinessSecStatus());
			// 收款按钮 已收金额 等于合同金额。不显示
			// 已收金额
			HaveReceiveRefundDto hrrDto = new HaveReceiveRefundDto();
			hrrDto.setRelationId(signed.getId());
			hrrDto.setDocType(DocTypeEnum.COLLECTION.getNo());
			hrrDto.setReceivablesType(ReceivablesTypeEnum.SIGNED.getNo());
			hrrDto.setTransferStatus("0");
			double haveCollection = haveReceiveRefundService.getRealAmount(hrrDto);
			if (new BigDecimal(haveCollection).compareTo(signed.getSignAmount()) == 0) {
				shouStatus = "1";
			} else {
				shouStatus = "0";
			}
			map.put("shouStatus", shouStatus);
			map.put("procInstId", StringUtils.isBlank(procInstId) ? signed.getProcInstId() : procInstId);
			NeedReceiveRefundDto needReceiveRefundDto = new NeedReceiveRefundDto();
			needReceiveRefundDto.setBusinessType("2");// 签约
			needReceiveRefundDto.setRelationId(signedId);
			map.put("auditStatus", signed.getAuditStatus());
			map.put("businessStatus", signed.getBusinessStatus());
			map.put("businessSecStatus", signed.getBusinessSecStatus());
			if (signed.getBusinessStatus().equals("2")) {
				BusinessAbnormaDto businessAbnormaDto = new BusinessAbnormaDto();
				businessAbnormaDto.setBusinessId(signedId);
				businessAbnormaDto.setBusinessType(BusinessAbnormaEnum.BusinessAbnorma_4.getNo());
				businessAbnormaDto.setAuditStatus(AuditStatusEnum.SUCCESS.getNo());
				ResponseList<BusinessAbnorma> businessAbnormas = businessAbnormaServiceFacade
						.findByDto(businessAbnormaDto);
				if (businessAbnormas.isSuccess() && businessAbnormas.getEntity() != null
						&& businessAbnormas.getEntity().size() != 0) {
					map.put("businessAbnormaId", businessAbnormas.getEntity().get(0).getId());
					map.put("huanStatus", "1");
				} else {
					map.put("huanStatus", "0");
				}
			} else if (!signed.getBusinessStatus().equals("3")) {
				BusinessAbnormaDto businessAbnormaDto = new BusinessAbnormaDto();
				businessAbnormaDto.setBusinessId(signedId);
				businessAbnormaDto.setBusinessType(BusinessAbnormaEnum.BusinessAbnorma_3.getNo());
				// businessAbnormaDto.setAuditStatus(AuditStatusEnum.AUDIT.getNo());
				ResponseList<BusinessAbnorma> businessAbnormas = businessAbnormaServiceFacade
						.findByDto(businessAbnormaDto);
				if (businessAbnormas.isSuccess() && businessAbnormas.getEntity() != null
						&& businessAbnormas.getEntity().size() != 0) {
					BusinessAbnorma abnorma = businessAbnormas.getEntity().get(0);
					map.put("businessAbnormaId", businessAbnormas.getEntity().get(0).getId());
					if (abnorma.getAuditStatus().equals("1")) {// 待提交隐藏
						map.put("huanStatus", "1");
					} else if (abnorma.getAuditStatus().equals("2")) {// 已退回显示
						map.put("huanStatus", "0");
					}
				} else {
					map.put("huanStatus", "0");
				}
			} else {// 已通过隐藏
				BusinessAbnormaDto businessAbnormaDto = new BusinessAbnormaDto();
				businessAbnormaDto.setBusinessId(signedId);
				businessAbnormaDto.setBusinessType(BusinessAbnormaEnum.BusinessAbnorma_3.getNo());
				businessAbnormaDto.setAuditStatus(AuditStatusEnum.SUCCESS.getNo());
				ResponseList<BusinessAbnorma> businessAbnormas = businessAbnormaServiceFacade
						.findByDto(businessAbnormaDto);
				if (businessAbnormas.isSuccess() && businessAbnormas.getEntity() != null
						&& businessAbnormas.getEntity().size() != 0) {
					map.put("businessAbnormaId", businessAbnormas.getEntity().get(0).getId());
					map.put("huanStatus", "1");
				} else {
					map.put("huanStatus", "0");
				}
			}
			if (signed.getDiscountAfterPrice() == null) {
				signed.setDiscountAfterPrice(new BigDecimal("0"));
			}
			String subscribeStr = JSON.toJSONString(signed);
			JSONObject signedRecordJson = JSONObject.parseObject(subscribeStr);
			signedRecordJson.put("contactTypeName",
					StringUtils.isNotBlank(signed.getContactType())
							? ContactTypeEnum.getByNo(signed.getContactType()).getDes()
							: "");
			signedRecordJson.put("decorationPaymentMethodName",
					StringUtils.isNotBlank(signed.getDecorationPaymentMethod())
							? DecorationPaymentMethodEnum.getByNo(signed.getDecorationPaymentMethod()).getDes()
							: "");
			signedRecordJson.put("paymentMethodName",
					StringUtils.isNotBlank(signed.getPaymentMethod())
							? PaymentMethodEnum.getByNo(signed.getPaymentMethod()).getDes()
							: "");
			signedRecordJson.put("dealCategoryName",
					StringUtils.isNotBlank(signed.getDealCategory())
							? DealCategoryEnum.getByNo(signed.getDealCategory()).getDes()
							: "");
			HashMap<String, Double> maps = signedServiceFacade.signedContractAmount(signed.getPayDepositId(),
					signed.getSubscribeId());
			Double payAepositAmount = 0d;
			if (null != maps.get("payAepositAmount")) {
				payAepositAmount = maps.get("payAepositAmount");
			}
			signedRecordJson.put("payAepositAmount", payAepositAmount);

			//判断是否工抵贷
			if("1".equals(signed.getIsFlag())){
				signedRecordJson.put("isFlag","是");
			}
			else{
				signedRecordJson.put("isFlag","否");
			}
			// 判断是否认购转签约，如果是则用已收认购金额-认筹转认购金额
			if (null != signed.getSubscribeId()) {
				Double subscribeAmount = 0d;
				if (null != maps.get("subscribeAmount")) {
					subscribeAmount = maps.get("subscribeAmount");
				}
				signedRecordJson.put("subscribeAmount", subscribeAmount - payAepositAmount);
			} else {
				signedRecordJson.put("subscribeAmount", "0");
			}

			map.put("signedRecord", signedRecordJson.toJSONString());
			JSONObject estateRecord = getEstateRecord(signed.getRoomId());
			estateRecord.put("calculateArea", signed.getCalculateArea());
			estateRecord.put("unitPrice", signed.getConversionPrice());
			estateRecord.put("totalPrice", signed.getLumpsumPrice());
			map.put("estateRecord", estateRecord.toJSONString());

			// 已退金额
			hrrDto.setRelationId(signedId);
			hrrDto.setDocType(DocTypeEnum.REFUND.getNo());
			hrrDto.setReceivablesType(ReceivablesTypeEnum.SIGNED.getNo());
			double haveRefund = haveReceiveRefundService.getRealAmount(hrrDto);
			// 是否可变更合同 false:不隐藏, true: 隐藏按钮
			boolean contactChange = true;
			if (haveCollection - haveRefund == 0) {
				contactChange = false;
			}
			map.put("contactChangeFlag", contactChange);

			JSONObject customerRecord = getCustomerRecord(signed.getCustomerId());
			map.put("customerRecord", customerRecord.toJSONString());
			// User user =
			// userServiceFacade.findById(signed.getAgentId()).getEntity();
			map.put("userName", signed.getUserName());
		}
		map.put("documentType", dtArray.toJSONString());
		map.put("processFlag", processFlag != null ? processFlag : "false");
		map.put("subscribeId", id);
		map.put("permitBtn", getPermissionBtnArray());
		map.put("process", process);
		map.put("menu", request.getParameter("menu"));
		map.put("payDepositOff", payDepositOff);
		map.put("back", request.getParameter("back"));
		if (!com.alibaba.druid.util.StringUtils.isEmpty(returnUrl)) {
			map.put("returnUrl", returnUrl.replace(",", "/").replace("(", "?").replace(")", "="));
			map.put("returnBackParam", returnUrl);
		}
		return "/customer/signed/view";
	}

	// 组装房源信息
	public JSONObject getEstateRecord(Long roomId) {
		JSONObject projectRoomJson = new JSONObject();
		Response<ProjectRoom> response = projectRoomServiceFacade.findById(roomId);
		if (response.isSuccess()) {
			ProjectRoom projectRoom = response.getEntity();
			projectRoomJson.put("combinedName", projectRoom.getCombinedName());
			projectRoomJson.put("buildingArea", projectRoom.getBuildingArea());
			projectRoomJson.put("sharingArea", projectRoom.getSharingArea());
			projectRoomJson.put("innerArea", projectRoom.getInnerArea());
			projectRoomJson.put("billingArea", projectRoom.getBillingArea());
			projectRoomJson.put("roomStatusName",
					StringUtils.isNotBlank(projectRoom.getRoomStatus())
							? RoomStatusEnum.getByNo(projectRoom.getRoomStatus()).getDes()
							: "");
		}
		return projectRoomJson;
	}

	// 组装客户信息
	public JSONObject getCustomerRecord(Long customerId) {
		JSONObject customerJson = new JSONObject();
		Response<Customer> response = customerServiceFacade.findById(customerId);
		if (response.isSuccess()) {
			Customer customer = response.getEntity();
			customerJson.put("customerName", customer.getCustomerName());
			BaseCodeValueDto bcvDto = new BaseCodeValueDto();
			bcvDto.setMerchantId(customer.getMerchantId());
			ResponseList<BaseCodeValue> bcvResList = baseCodeValueServiceFacade.selectListFilterDelFlag(bcvDto);
			Map<Long, String> bcvMap = new HashMap<Long, String>();
			if (bcvResList.isSuccess()) {
				List<BaseCodeValue> bcvList = bcvResList.getEntity();
				for (BaseCodeValue bcv : bcvList) {
					bcvMap.put(bcv.getId(), bcv.getCodeName());
				}
			}
			if (StringUtils.isNotBlank(customer.getPeDocumentType())) {
				customerJson.put("peDocumentTypeName", bcvMap.get(Long.parseLong(customer.getPeDocumentType())));
			}
			customerJson.put("peDocumentNumber", customer.getPeDocumentNumber());
			customerJson.put("customerPhone", customer.getCustomerPhone());
			customerJson.put("peContactAddress", customer.getPeContactAddress());
			customerJson.put("pePostcode", customer.getPePostcode());
			if (StringUtils.isNotBlank(customer.getCustomerOrigin())) {
				customerJson.put("customerOriginName", bcvMap.get(Long.parseLong(customer.getCustomerOrigin())));
			}
		}
		return customerJson;
	}

	// 查看
	@RequestMapping(value = "view", method = RequestMethod.POST)
	@ResponseBody
	public AjaxRes view(Long id) {
		AjaxRes ar = getAjaxRes();
		/*
		 * 1.判断权限2.调用查看接口3.返回信息
		 */
		if (ar.setNoAuth(doSecurityIntercept(Const.RESOURCES_TYPE_BUTTON, "customer:signed:view"))) {
			try {
				Response<Signed> response = signedServiceFacade.findById(id);
				if (response.isSuccess()) {
					ar.setSucceed(response.getEntity());
				} else {
					ar.setFailMsg(Const.DATA_FAIL);
				}
			} catch (Exception e) {
				logger.error(e.toString(), e);
				ar.setFailMsg(Const.DATA_FAIL);
			}
		}
		return ar;
	}

	// 修改
	@RequestMapping(value = "edit", method = RequestMethod.POST)
	@ResponseBody
	public AjaxRes edit(SignedDto dto) {
		AjaxRes ar = getAjaxRes();
		/*
		 * 1.判断权限2.调用修改接口3.返回信息
		 */
		if (ar.setNoAuth(doSecurityIntercept(Const.RESOURCES_TYPE_BUTTON, "customer:signed:edit"))) {
			try {
				Response<Integer> response = signedServiceFacade.updateByPrimaryKey(dto, true);
				if (response.isSuccess()) {
					ar.setSucceedMsg(Const.UPDATE_SUCCEED);
				} else {
					ar.setFailMsg(Const.UPDATE_FAIL);
				}
			} catch (Exception e) {
				logger.error(e.toString(), e);
				ar.setFailMsg(Const.UPDATE_FAIL);
			}
		}
		return ar;
	}

	// 删除
	@RequestMapping(value = "delete", method = RequestMethod.POST)
	@ResponseBody
	public AjaxRes delete(Long id) {
		AjaxRes ar = getAjaxRes();
		/*
		 * 1.判断权限2.调用查看接口3.返回信息
		 */
		if (ar.setNoAuth(doSecurityIntercept(Const.RESOURCES_TYPE_BUTTON, "customer:signed:delete"))) {
			try {
				Response<Integer> response = signedServiceFacade.deleteByPrimaryKey(id);
				if (response.isSuccess()) {
					ar.setSucceedMsg(Const.DEL_SUCCEED);
				} else {
					ar.setFailMsg(Const.DEL_FAIL);
				}
			} catch (Exception e) {
				logger.error(e.toString(), e);
				ar.setFailMsg(Const.DEL_FAIL);
			}
		}
		return ar;
	}

	// 分页查询
	@RequestMapping(value = "list", method = RequestMethod.POST)
	@ResponseBody
	public Page<SignedDto> list(SignedDto dto, Integer limit, Integer page) {
		/*
		 * 1.判断权限2.调用分页查询接口3.返回信息
		 */
		if (doSecurityIntercept(Const.RESOURCES_TYPE_BUTTON, "marketing:signed:list")) {
			try {
				dto = setSignedQueryDto(dto);
				Response<Page<SignedDto>> response = signedService.getSignedDtoList(dto, limit, page);
				if (response.isSuccess()) {
					Page<SignedDto> pages = response.getEntity();
					pages.setPageNumber(page);
					return pages;
				} else {
				}
			} catch (Exception e) {
				logger.error(e.toString(), e);
			}
		}
		return new Page<SignedDto>();
	}

	@RequestMapping(value = "signedInfoExport")
	public void signedInfoExport(String value, HttpServletResponse response) {
		AjaxRes ar = getAjaxRes();
		try {
			if (ar.setNoAuth(doSecurityIntercept(Const.RESOURCES_TYPE_BUTTON, "customer:signed:export"))) {
				String jsonStr = URLDecoder.decode(value, "utf-8");
				SignedDto reqDto = JSONObject.parseObject(jsonStr, SignedDto.class);
				reqDto = setSignedQueryDto(reqDto);
				List<SignedDto> sigList = signedService.querySignedDtoExport(reqDto);
				String[] name = new String[] { "签约信息" }; // sheet信息
				List<String[]> headerList = new ArrayList<String[]>(); // 表头集合
				List<List<Map<String, String>>> list = new ArrayList<List<Map<String, String>>>(); // 数据集合
				// 设置表头字段
				String[] header = new String[] { "签约日期", "客户名称", "房号", "户型", "计价面积(平方米)", "签约单价(元)", "合同金额(元)", "付款方式",
						"未收款(元)", "已收金额(元)", "是否逾期未付款", "逾期天数", "逾期未付款金额(元)", "经纪人", "业务状态", "审核状态" };
				headerList.add(header);
				List<Map<String, String>> listMap = signedService.returnFieldSigned(sigList, header);
				list.add(listMap);
				ExcelUtil.exportExcel(list, headerList, name, response);
			}
		} catch (Exception e) {
			logger.error("signedInfoExport error: ", e);
		}

	}

	public SignedDto setSignedQueryDto(SignedDto dto) {

		// 审核时间
		if (dto.getCheckDateBefore() != null && !dto.getCheckDateBefore().equals("")) {
			dto.setCheckDateBefore(dto.getCheckDateBefore() + " 00:00:00");
		}
		if (dto.getCheckDateAfter() != null && !dto.getCheckDateAfter().equals("")) {
			dto.setCheckDateAfter(dto.getCheckDateAfter() + " 23:59:59");
		}
		// 签约日期
		if (dto.getDidTimeBefore() != null && !dto.getDidTimeBefore().equals("")) {
			dto.setDidTimeBefore(dto.getDidTimeBefore() + " 00:00:00");
		}
		if (dto.getDidTimeAfter() != null && !dto.getDidTimeAfter().equals("")) {
			dto.setDidTimeAfter(dto.getDidTimeAfter() + " 23:59:59");
		}
		// 录入时间
		if (dto.getCreateTimeBefore1() != null && !dto.getCreateTimeBefore1().equals("")) {
			dto.setCreateTimeBefore1(dto.getCreateTimeBefore1() + " 00:00:00");
		}
		if (dto.getCreateTimeAfter1() != null && !dto.getCreateTimeAfter1().equals("")) {
			dto.setCreateTimeAfter1(dto.getCreateTimeAfter1() + " 23:59:59");
		}
		dto.setOrders(" t.create_time desc ");
		User user = ShiroUtil.getCurrentUser();
		dto.setMerchantId(user.getMerchantId());
		dto.setPermissionUserId(user.getId());

		// 项目数据权限资源缓存
		String resourcesCode = ShiroUtil.getDataPermissionResources(dto.getResourcesName());
		if (null == dto.getResourcesCode() || "".equals(dto.getResourcesCode())) {
			dto.setResourcesCode(resourcesCode);
		} else if ("".equals(resourcesCode)) {
			ShiroUtil.setDataPermissionResources(dto.getResourcesName(), dto.getResourcesCode());
		}
		return dto;
	}

	// 跳转退房页面
	@RequestMapping(value = "toCheckOut")
	@AvoidDuplicateSubmission(needSaveToken = true)
	public String toCheckOut(String signedId, ModelMap map) {
		map.put("signedId", signedId);
		Long projectId = signedServiceFacade.findById(new Long(signedId)).getEntity().getProjectId();
		map.put("specialFlow", projectServiceFacade.findById(projectId).getEntity().getSpecialFlow());
		return "/customer/signed/checkout";
	}

	// 加载退房/合同变更表单数据
	@RequestMapping(value = "loadCheckOutInfo")
	public @ResponseBody ExtResultVo loadCheckOutInfo(Long signedId, String businessAbnormaId) {
		ExtResultVo vo = new ExtResultVo();
		vo.setSuccess(true);
		vo.setData(new JSONObject().toJSONString());
		JSONObject jsonObject = oaDataService.loadSignedChangeNameInfo(signedId, businessAbnormaId);
		vo.setData(jsonObject.toJSONString());
		return vo;
	}

	// 提交退房申请
	@RequestMapping(value = "submitCheckOut")
	@AvoidDuplicateSubmission(needRemoveToken = true)
	public @ResponseBody AjaxRes submitCheckOut(Long signedId, String remark,String backType, String fileUrlArr, String imageType,
			HttpServletRequest request, BigDecimal liquidat) {
		AjaxRes ar = getAjaxRes();
		// 操作失败时,重新刷新提交Token
		String newToken = TokenProcessor.getInstance().generateToken(request);
		request.getSession(false).setAttribute("token", newToken);
		User user = ShiroUtil.getCurrentUser();
		Response<Signed> signedResponse = new Response<Signed>();
		try {
			signedResponse = signedServiceFacade.findById(signedId);
			if (!signedResponse.isSuccess() || null == signedResponse.getEntity()) {
				ar.setFailMsg(Const.SAVE_FAIL);
				return ar;
			}
			Long projectId = signedResponse.getEntity().getProjectId();
			if (null == projectId) {
				ar.setFailMsg("项目不存在!");
				return ar;
			}
			// 动态获取价格方案流程KEY
			ProcessTypeEnums processType = null;
			Project project = projectServiceFacade.findById(projectId).getEntity();
			if (project.getSpecialFlow() != null && project.getSpecialFlow().equals("1")) {
				processType = ProcessTypeEnums.PROCESS_KEY_22;
			} else {
				processType = ProcessTypeEnums.PROCESS_KEY_15;
			}
			String startProcessKey = activitiProcessService.getProcessKey(user.getMerchantId(), projectId, processType);
			if (StringUtils.isEmpty(startProcessKey)) {
				ar.setFailMsg("项目未设置价格方案流程,请去项目流程菜单配置！");
				return ar;
			}
			String processDefinitionKey = startProcessKey;
			boolean isSeting = activitiProcessService.checkNodeUser(user.getMerchantId(), projectId,
					processDefinitionKey);
			if (!isSeting) {
				ar.setFailMsg("签约退房审批流程节点人员未设置");
				return ar;
			}
			BusinessAbnormaDto dto = new BusinessAbnormaDto();
			dto.setBusinessId(signedId);
			dto.setBusinessType(BusinessAbnormaEnum.BusinessAbnorma_4.getNo());
			dto.setAuditStatus(AuditStatusEnum.TOSUBMIT.getNo());
			dto.setRemark(remark);
			dto.setBackType(backType);
			dto.setMerchantId(user.getMerchantId());
			dto.setCreateUserId(user.getId());
			dto.setDelFlag("0");
			dto.setUpdateUserId(user.getId());
			dto.setUpdateTime(new Date());
			dto.setUserCode(user.getUserCode());
			dto.setAccessCode(signedResponse.getEntity().getAccessCode());
			Response<BusinessAbnormaDto> response = businessAbnormaServiceFacade.save(dto);
			if (response.isSuccess()) {
				// 启动流程
				Map<String, Object> variables = new HashMap<String, Object>();
				identityService.setAuthenticatedUserId(user.getUserAccount());
				String pid = activitiProcessService.startProcessInstance(user.getMerchantId(), projectId,
						processDefinitionKey, response.getEntity().getId().toString(), variables);
				// 更新审批状态
				BusinessAbnormaDto updateDto = new BusinessAbnormaDto();
				updateDto.setId(response.getEntity().getId());
				updateDto.setAuditStatus(AuditStatusEnum.AUDIT.getNo());
				updateDto.setProcInstId(pid);
				updateDto.setCheckDate(new Date());
				businessAbnormaServiceFacade.updateByPrimaryKey(updateDto, true);
				ar.setSucceed(response.getEntity().getId().toString());
				// 保存流程附件
				if (StringUtils.isNotBlank(fileUrlArr)) {
					// 添加流程审核需要的图片
					wsImageService.uploadAttachment(fileUrlArr, String.valueOf(response.getEntity().getId()), imageType,
							signedResponse.getEntity().getAccessCode());
				}
				// 更新没收没收违约金
				if ("1".equals(project.getSpecialFlow())) {
					SignedDto liquidatDato = new SignedDto();
					liquidatDato.setId(signedId);
					liquidatDato.setLiquidat(liquidat);
					signedServiceFacade.updateByPrimaryKey(liquidatDato, true);
				}

			} else {
				ar.setFailMsg(Const.SAVE_FAIL);
			}
		} catch (Exception ex) {
			//新增业务操作异常记录
			businessLogServiceFacade.saveExceptionLog(user, "新增签约退房", JSONObject.toJSONString(signedResponse), JSONObject.toJSONString(ex));
			
			logger.error("新增签约退房", ex);
			ar.setFailMsg(Const.SAVE_FAIL);
		}
		// 操作失败,重置防重复提交Token
		if (Const.FAIL == ar.getRes()) {
			ar.setObj(newToken);
		}
		return ar;
	}

	// 退房申请详情
	@RequestMapping(value = "toCheckOutView")
	public String toCheckOutView(String id, ModelMap map, String processFlag, String back) {
		Response<BusinessAbnorma> businessAbnormaResponse = businessAbnormaServiceFacade.findById(Long.valueOf(id));
		Long projectId = signedServiceFacade.findById(businessAbnormaResponse.getEntity().getBusinessId()).getEntity()
				.getProjectId();
		String specialFlow = projectServiceFacade.findById(projectId).getEntity().getSpecialFlow();
		map.put("signedId", businessAbnormaResponse.getEntity().getBusinessId());
		map.put("businessAbnormaId", id);
		map.put("processFlag", processFlag);
		map.put("back", back);
		map.put("auditStatus", businessAbnormaResponse.getEntity().getAuditStatus());
		map.put("procInstId", businessAbnormaResponse.getEntity().getProcInstId());
		map.put("specialFlow", specialFlow);
		return "/customer/signed/checkoutView";
	}

	// 跳转更名页面
	@RequestMapping(value = "toChangeName")
	@AvoidDuplicateSubmission(needSaveToken = true)
	public String toChangeName(String signedId, ModelMap map) {
		map.put("signedId", signedId);
		long projectId = 0L;
		if (StringUtils.isNotBlank(signedId)) {
			Response<SignedInfo> response = signedServiceFacade.findByIdInfo(Long.valueOf(signedId));
			if (response.isSuccess() && response.getEntity() != null) {
				map.put("projectId", response.getEntity().getProjectId());
				projectId = response.getEntity().getProjectId();
			}
		}
		User user = ShiroUtil.getCurrentUser();
		String typeName = BaseCodeTypeEnum.getByNo(BaseCodeTypeEnum.TYPE_TWELVE.getNo()).getDes();
		BaseCodeValueDto bcvDto = new BaseCodeValueDto();
		bcvDto.setMerchantId(user.getMerchantId());
		bcvDto.setTypeName(typeName);
		bcvDto.setProjectId(projectId);
		bcvDto.setDelFlag(DelFlagEnum.UNDEL.getNo());
		// *1解决数字排序问题.例如 1,2,10.排序后会显示成 1,10,2
		bcvDto.setOrders("t.sort*1");
		JSONArray dtArray = JSONArray.parseArray(baseCodeValueServiceFacade.getBcvJsonArray(bcvDto));
		map.put("documentType", dtArray.toJSONString());
		return "/customer/signed/changeName";
	}

	// 提交更名
	@RequestMapping(value = "submitChangeName")
	@AvoidDuplicateSubmission(needRemoveToken = true)
	public @ResponseBody AjaxRes submitChangeName(HttpServletRequest request, String params) {
		AjaxRes ar = getAjaxRes();
		// 操作失败时,重新刷新提交Token
		String newToken = TokenProcessor.getInstance().generateToken(request);
		request.getSession(false).setAttribute("token", newToken);
		User user = ShiroUtil.getCurrentUser();
		try {
			JSONObject paramsJson = JSON.parseObject(params);
			Long signedId = paramsJson.getLong("signedId");
			String remark = paramsJson.getString("remark");
			Response<Signed> signedResponse = signedServiceFacade.findById(signedId);
			if (!signedResponse.isSuccess() || null == signedResponse.getEntity()) {
				ar.setFailMsg(Const.SAVE_FAIL);
				return ar;
			}
			// 是否存在审核中的延期签约记录，如果存在，则不能再次发起
			BusinessAbnormaDto queryDto = new BusinessAbnormaDto();
			queryDto.setBusinessId(signedId);
			queryDto.setBusinessType(BusinessAbnormaEnum.BusinessAbnorma_6.getNo());
			ResponseList<BusinessAbnorma> responseList = businessAbnormaServiceFacade.findByDto(queryDto);
			boolean isSubmit = true;
			if (responseList.isSuccess() && null != responseList.getEntity()) {
				List<BusinessAbnorma> abList = responseList.getEntity();
				for (BusinessAbnorma ab : abList) {
					String auditStatus = ab.getAuditStatus();
					if (auditStatus.equals(AuditStatusEnum.AUDIT.getNo())
							|| auditStatus.equals(AuditStatusEnum.TOSUBMIT.getNo())) {
						isSubmit = false;
						break;
					}
				}
			}
			if (!isSubmit) {
				ar.setFailMsg("存在审核中更名记录，不能再次发起");
				return ar;
			}
			Long projectId = signedResponse.getEntity().getProjectId();
			if (null == projectId) {
				ar.setFailMsg("项目不存在!");
				return ar;
			}
			// 动态获取价格方案流程KEY
			String startProcessKey = activitiProcessService.getProcessKey(user.getMerchantId(), projectId,
					ProcessTypeEnums.PROCESS_KEY_8);
			if (StringUtils.isEmpty(startProcessKey)) {
				ar.setFailMsg("项目未设置更名审批流程,请去项目流程菜单配置！");
				return ar;
			}
			boolean isSeting = activitiProcessService.checkNodeUser(user.getMerchantId(), projectId, startProcessKey);
			if (!isSeting) {
				ar.setFailMsg("更名审批流程节点人员未设置");
				return ar;
			}
			Signed signed = signedResponse.getEntity();

			BusinessAbnormaDto dto = new BusinessAbnormaDto();
			dto.setBusinessId(signedId);
			dto.setBusinessType(BusinessAbnormaEnum.BusinessAbnorma_6.getNo());
			dto.setAuditStatus(AuditStatusEnum.TOSUBMIT.getNo());
			dto.setRemark(remark);
			dto.setMerchantId(user.getMerchantId());
			dto.setCreateUserId(user.getId());
			dto.setDelFlag("0");
			dto.setUpdateUserId(user.getId());
			dto.setUpdateTime(new Date());
			dto.setUserCode(user.getUserCode());
			dto.setAccessCode(signedResponse.getEntity().getAccessCode());
			Response<BusinessAbnormaDto> response = businessAbnormaServiceFacade.save(dto);
			if (response.isSuccess()) {
				// 新共同购房者
				JSONArray familyMembers = paramsJson.getJSONArray("familyMember");
				// 新客户信息
				JSONArray newFamilyMembers = paramsJson.getJSONArray("newFamilyMember");
				// 保存新共同购房者信息
				if (familyMembers.size() > 0) {
					ar = getAr(ar, familyMembers, signed, response, user, MemberTypeEnum.SIGNEDCHANGENAME.getNo(),
							null);
					if (ar.getRes() == 0) {
						return ar;
					}
				}
				// 保存新客户信息
				if (newFamilyMembers.size() > 0) {
					ar = getAr(ar, newFamilyMembers, signed, response, user, MemberTypeEnum.N_CUSTOMER_INFO.getNo(),
							null);
					if (ar.getRes() == 0) {
						return ar;
					}
				}

				// 保存原客户信息
				Response<SignedDto> response2 = signedServiceFacade.selectSignedCustomer(signedId);
				if (response2.isSuccess() && response2.getEntity() != null) {
					JSONArray yFamilyMember = new JSONArray();
					FamilyMemberDto dto2 = new FamilyMemberDto();
					dto2.setDocumentType(response2.getEntity().getDtype());
					dto2.setDocumentNumber(response2.getEntity().getDocumentNumber());
					dto2.setMobile(response2.getEntity().getMobile());
					dto2.setMemberName(response2.getEntity().getMemberName());
					yFamilyMember.add(JSON.toJSONString(dto2));
					ar = getAr(ar, yFamilyMember, signed, response, user, MemberTypeEnum.Y_CUSTOMER_INFO.getNo(),
							response2.getEntity().getCustomerId());
					if (ar.getRes() == 0) {
						return ar;
					}
				}
				// 保存原共同购房者信息
				FamilyMemberDto fmd = new FamilyMemberDto();
				fmd.setMemberType("4");
				fmd.setBuyId(signedId);
				ResponseList<FamilyMember> response3 = familyMemberServiceFacade.findByDto(fmd);
				if (response3.isSuccess() && response3.getEntity() != null && response3.getEntity().size() > 0) {
					for (FamilyMember familyMember : response3.getEntity()) {
						FamilyMemberDto memberDto = new FamilyMemberDto();
						BeanUtil.convert2T(memberDto, familyMember);
						memberDto.setBuyId(response.getEntity().getId());
						memberDto.setMemberType(MemberTypeEnum.Y_COMMON_INFO.getNo());
						Response<FamilyMemberDto> familyMemberDtoResponse = familyMemberServiceFacade.save(memberDto);
						if (!familyMemberDtoResponse.isSuccess()) {
							ar.setFailMsg(Const.SAVE_FAIL);
							break;
						}
					}
				}
				Map<String, Object> variables = new HashMap<String, Object>();
				// 启动流程
				identityService.setAuthenticatedUserId(user.getUserAccount());
				String pid = activitiProcessService.startProcessInstance(user.getMerchantId(), projectId,
						startProcessKey, response.getEntity().getId().toString(), variables);
				// 更新审批状态
				BusinessAbnormaDto updateDto = new BusinessAbnormaDto();
				updateDto.setId(response.getEntity().getId());
				updateDto.setAuditStatus(AuditStatusEnum.AUDIT.getNo());
				updateDto.setProcInstId(pid);
				updateDto.setCheckDate(new Date());
				businessAbnormaServiceFacade.updateByPrimaryKey(updateDto, true);
				// 更名审批支持附件上传(ym)
				String fileUrlArr = paramsJson.getString("fileUrlArr");
				String imageType = paramsJson.getString("imageType");
				if (StringUtils.isNotEmpty(fileUrlArr)) {
					// 添加流程审核需要的图片
					wsImageService.uploadAttachment(fileUrlArr, String.valueOf(response.getEntity().getId()), imageType,
							signedResponse.getEntity().getAccessCode());
				}

				// 更名审批支持附件上传(ym)

				ar.setSucceed(response.getEntity().getId());
			} else {
				ar.setFailMsg(Const.SAVE_FAIL);
			}
		} catch (Exception ex) {
			
			//新增业务操作异常记录
			businessLogServiceFacade.saveExceptionLog(user, "新增签约更名", params, JSONObject.toJSONString(ex));
			
			
			logger.error("新增签约更名", ex);
			ar.setFailMsg(Const.SAVE_FAIL);
			
		}
		// 操作失败,重置防重复提交Token
		if (Const.FAIL == ar.getRes()) {
			ar.setObj(newToken);
		}
		return ar;
	}

	private AjaxRes getAr(AjaxRes ar, JSONArray familyMembers, Signed signed, Response<BusinessAbnormaDto> response,
			User user, String no, Long customerId) {
		if (null != familyMembers && familyMembers.size() > 0) {
			for (int i = 0; i < familyMembers.size(); i++) {
				String familyMemberStr = (String) familyMembers.get(i);
				FamilyMemberDto familyMemberRow = JSONObject.parseObject(familyMemberStr, FamilyMemberDto.class);
				if (customerId != null) {
					familyMemberRow.setCustomerId(customerId);
				} else {
					familyMemberRow.setCustomerId(signed.getCustomerId());
				}
				familyMemberRow.setBuyId(response.getEntity().getId());
				familyMemberRow.setProjectId(signed.getProjectId());
				familyMemberRow.setProjectCode(signed.getProjectCode());
				familyMemberRow.setMemberType(no);
				familyMemberRow.setAccessCode(signed.getAccessCode());
				familyMemberRow.setUserCode(user.getUserCode());
				familyMemberRow.setMerchantId(user.getMerchantId());
				familyMemberRow.setCreateUserId(user.getId());
				familyMemberRow.setDelFlag("0");
				familyMemberRow.setUpdateUserId(user.getId());
				familyMemberRow.setUpdateTime(new Date());
				familyMemberRow.setIsDefault("0");
				familyMemberRow.setSex("3");
				Response<FamilyMemberDto> familyMemberDtoResponse = familyMemberServiceFacade.save(familyMemberRow);
				if (!familyMemberDtoResponse.isSuccess()) {
					ar.setFailMsg(Const.SAVE_FAIL);
				} else {
					ar.setRes(Const.SUCCEED);
				}
			}
		}
		return ar;
	}

	// 跳转更名页面
	@RequestMapping(value = "toChangeNameView")
	public String toChangeNameView(String id, ModelMap map, String processFlag) {
		Response<BusinessAbnorma> businessAbnormaResponse = businessAbnormaServiceFacade.findById(Long.valueOf(id));
		map.put("businessAbnormaId", id);
		map.put("processFlag", processFlag);
		map.put("auditStatus", businessAbnormaResponse.getEntity().getAuditStatus());
		map.put("procInstId", businessAbnormaResponse.getEntity().getProcInstId());
		User user = ShiroUtil.getCurrentUser();
		String typeName = BaseCodeTypeEnum.getByNo(BaseCodeTypeEnum.TYPE_TWELVE.getNo()).getDes();
		BaseCodeValueDto bcvDto = new BaseCodeValueDto();
		bcvDto.setMerchantId(user.getMerchantId());
		bcvDto.setTypeName(typeName);
		bcvDto.setDelFlag(DelFlagEnum.UNDEL.getNo());
		// *1解决数字排序问题.例如 1,2,10.排序后会显示成 1,10,2
		bcvDto.setOrders("t.sort*1");
		JSONArray dtArray = JSONArray.parseArray(baseCodeValueServiceFacade.getBcvJsonArray(bcvDto));
		map.put("documentType", dtArray.toJSONString());
		String businessType = businessAbnormaResponse.getEntity().getBusinessType();
		if (businessType.equals(BusinessAbnormaEnum.BusinessAbnorma_11.getNo())) {
			map.put("subscribeId", businessAbnormaResponse.getEntity().getBusinessId());
			return "/customer/subscribe/changeNameView";
		}
		map.put("signedId", businessAbnormaResponse.getEntity().getBusinessId());

		return "/customer/signed/changeNameView";

	}

	/**
	 * 客户信息 功能描述: <br>
	 * 〈功能详细描述〉
	 * 
	 * @param signedId
	 * @return
	 * @see [相关类/方法](可选)
	 * @since [产品/模块版本](可选)
	 */
	@RequestMapping(value = "selectSignedCustomer", method = RequestMethod.POST)
	@ResponseBody
	public AjaxRes selectSignedCustomer(Long signedId) {
		AjaxRes ar = getAjaxRes();
		try {
			Response<SignedDto> response = signedServiceFacade.selectSignedCustomer(signedId);
			if (response.isSuccess() && response.getEntity() != null) {
				ar.setSucceed(response.getEntity());
			} else {
				ar.setRes(Const.FAIL);
			}
		} catch (Exception e) {
			logger.error(e.toString(), e);
			ar.setRes(10000);
			ar.setFailMsg(Const.DATA_FAIL);
		}
		return ar;
	}

	// marketing:signed:add
	@RequestMapping(value = "toEdit")
	@AvoidDuplicateSubmission(needSaveToken = true)
	public String toEdit(ModelMap map, String id, HttpServletRequest request, String returnUrl,
			String isChooseCustomer) {
		if (doSecurityIntercept(Const.RESOURCES_TYPE_BUTTON, "marketing:signed:add")) {
			Boolean showChooseCustomer = Boolean.FALSE;
			User user = ShiroUtil.getCurrentUser();
			// 认筹开关,默认未关闭(false) ,true已关闭
			boolean payDepositOff = false;
			Response<Boolean> response2 = merchantServiceFacade.merPayDepositOff(user.getMerchantId());
			if (response2.isSuccess()) {
				payDepositOff = response2.getEntity();
			}

			Response<SignedInfo> signedInfoRes = signedServiceFacade.findByIdInfo(Long.parseLong(id));

			// 查询菜单按钮权限
			map.put("permitBtn", getPermissionBtnArray());
			map.put("userId", user.getId());
			String typeName = BaseCodeTypeEnum.getByNo(BaseCodeTypeEnum.TYPE_TWELVE.getNo()).getDes();
			BaseCodeValueDto bcvDto = new BaseCodeValueDto();
			bcvDto.setMerchantId(user.getMerchantId());
			bcvDto.setTypeName(typeName);
			bcvDto.setDelFlag(DelFlagEnum.UNDEL.getNo());
			bcvDto.setProjectId(signedInfoRes.getEntity().getProjectId());
			// *1解决数字排序问题.例如 1,2,10.排序后会显示成 1,10,2
			bcvDto.setOrders("t.sort*1");
			JSONArray dtArray = JSONArray.parseArray(baseCodeValueServiceFacade.getBcvJsonArray(bcvDto));
			map.put("documentType", dtArray.toJSONString());

			JSONArray pmArray = new JSONArray();
			for (PaymentMethodEnum dt : PaymentMethodEnum.values()) {
				JSONObject row = new JSONObject();
				row.put("value", dt.getNo());
				row.put("name", dt.getDes());
				pmArray.add(row);
			}
			map.put("paymentMethods", pmArray.toJSONString());

			JSONArray ctArray = new JSONArray();
			for (ContactTypeEnum dt : ContactTypeEnum.values()) {
				JSONObject row = new JSONObject();
				row.put("value", dt.getNo());
				row.put("name", dt.getDes());
				ctArray.add(row);
			}
			map.put("contactTypes", ctArray.toJSONString());

			map.put("currentUserName", user.getUserName());
			map.put("payDeposit", new PayDeposit());


			SignedInfo signedInfo = new SignedInfo();
			String customerId = "";
			String roomId = "";
			String payDepositId = "";
			String subscribeId = "";
			if (signedInfoRes.isSuccess()) {
				signedInfo = signedInfoRes.getEntity();
				String extraInformation = signedInfo.getExtraInformation();
				JSONObject extraInfoJson = JSONObject.parseObject(extraInformation);
				signedInfo.setExtraInformation("");
				map.put("signedInfo", JSONObject.toJSONString(signedInfo));
				map.put("extraInformation", extraInfoJson.toJSONString());
				customerId = String.valueOf(signedInfo.getCustomerId());
				roomId = String.valueOf(signedInfo.getRoomId());
				payDepositId = String.valueOf(signedInfo.getPayDepositId());
				subscribeId = String.valueOf(signedInfo.getSubscribeId());
			}

			if (StringUtils.isNotEmpty(payDepositId) && "null" != payDepositId) {
				Response<PayDeposit> response = payDepositServiceFacade.findById(Long.valueOf(payDepositId));
				if (response.isSuccess() && null != response.getEntity()) {
					PayDeposit payDeposit = response.getEntity();
					map.put("payDeposit", payDeposit);
					map.put("signedContractAmount", net.sf.json.JSONArray
							.fromObject(signedServiceFacade.signedContractAmount(payDeposit.getId(), null)));
				}

			}

			if (StringUtils.isNotBlank(subscribeId) && "null" != subscribeId) {
				Response<Subscribe> response = subscribeServiceFacade.findById(Long.valueOf(subscribeId));
				if (response.isSuccess() && null != response.getEntity()) {
					Subscribe subscribe = response.getEntity();
					HaveReceiveRefundDto entity = new HaveReceiveRefundDto();
					entity.setDocType("0");
					entity.setReceivablesType("1");
					entity.setRelationId(Long.valueOf(subscribeId));
					Double amount = haveReceiveRefundService.getRealAmount(entity);
					subscribe.setDepositReceivable(new BigDecimal(amount));
					map.put("subscribe", subscribe);
					map.put("signedContractAmount", net.sf.json.JSONArray
							.fromObject(signedServiceFacade.signedContractAmount(null, subscribe.getId())));
				}
			} else {
				map.put("subscribe", new Subscribe());
			}
			if (!StringUtils.isBlank(customerId) && "null" != customerId) {
				/*map.put("signedContractAmount",
						net.sf.json.JSONArray.fromObject(signedServiceFacade.signedContractAmount(null, null)));*/
				map.put("customerId", customerId);
				Response<Customer> customerResponse = customerServiceFacade.findById(Long.valueOf(customerId));
				if (customerResponse.isSuccess() && null != customerResponse.getEntity()) {
					map.put("customerProjectId", customerResponse.getEntity().getProjectId());
				}
			}
			if (!StringUtils.isBlank(roomId) && "null" != roomId) {
				/*map.put("signedContractAmount",
						net.sf.json.JSONArray.fromObject(signedServiceFacade.signedContractAmount(null, null)));*/
				map.put("roomId", roomId);
			}
			map.put("menu", request.getParameter("menu"));
			if (!com.alibaba.druid.util.StringUtils.isEmpty(returnUrl)) {
				map.put("returnUrl", returnUrl.replace(",", "/").replace("(", "?").replace(")", "="));
			}

			map.put("projectId", request.getParameter("projectId"));
			map.put("payDepositOff", payDepositOff);
			if (StringUtils.isNotBlank(isChooseCustomer))
				showChooseCustomer = Boolean.TRUE;
			map.put("showChooseCustomer", showChooseCustomer);
			return "/customer/signed/edit";
		}
		return Const.NO_AUTHORIZED_URL;
	}

	// 加载延期付款表单数据
	@RequestMapping(value = "loadDeferredPaymentInfo")
	public @ResponseBody ExtResultVo loadDeferredPaymentInfo(Long signedId) {
		ExtResultVo vo = new ExtResultVo();
		vo.setSuccess(true);
		vo.setData(new JSONObject().toJSONString());
		Response<SignedInfo> signedResponse = signedServiceFacade.findByIdInfo(signedId);
		if (signedResponse.isSuccess() && null != signedResponse.getEntity()) {
			Signed signed = signedResponse.getEntity();
			String signedStr = JSON.toJSONString(signed);
			JSONObject data = JSONObject.parseObject(signedStr);
			// 客户名称
			Response<Customer> customerResponse = customerServiceFacade.findById(signed.getCustomerId());
			if (customerResponse.isSuccess() && null != customerResponse.getEntity()) {
				data.put("customerName", customerResponse.getEntity().getCustomerName());
			} else {
				data.put("customerName", "");
			}

			// 房号
			Response<ProjectRoom> projectRoomResponse = projectRoomServiceFacade.findById(signed.getRoomId());
			if (projectRoomResponse.isSuccess() && null != projectRoomResponse.getEntity()) {
				data.put("roomName", projectRoomResponse.getEntity().getCombinedName());
				PropertyTypeEnum enumOject = PropertyTypeEnum
						.getByNo(projectRoomResponse.getEntity().getPropertyType());
				data.put("propertyTypeName", enumOject == null ? "" : enumOject.getDes());
			} else {
				data.put("roomName", "");
				data.put("propertyTypeName", "");
			}

			Response<User> userResponse = userServiceFacade.findById(signed.getAgentId());
			if (userResponse.isSuccess() && null != userResponse.getEntity()) {
				data.put("agentName", userResponse.getEntity().getUserName());
			} else {
				data.put("agentName", "");
			}

			// 付款方式
			PaymentMethodEnum paymentMethodEnum = PaymentMethodEnum.getByNo(signed.getPaymentMethod());
			if (null != paymentMethodEnum) {
				data.put("paymentMethodName", paymentMethodEnum.getDes());
			} else {
				data.put("paymentMethodName", "");
			}
			vo.setData(data.toJSONString());
		}
		return vo;
	}

	// 加载延期付款表单数据
	@RequestMapping(value = "loadDeferredPaymentDetail")
	public @ResponseBody ExtResultVo loadDeferredPaymentDetail(Long id) {
		JSONObject jsonObject = new JSONObject();
		ExtResultVo vo = new ExtResultVo();
		vo.setSuccess(true);
		jsonObject = oaDataService.loadDeferredPaymentDetail(id);
		vo.setData(jsonObject.toJSONString());
		return vo;
	}

	// 查看
	@RequestMapping(value = "toDeferredPaymentIS", method = RequestMethod.POST)
	@ResponseBody
	public AjaxRes toDelaySignedIS(Long signedId) {
		AjaxRes ar = getAjaxRes();
		ar.setRes(Const.SUCCEED);
		ar.setResMsg("0");
		try {
			// 延期收款绑定的是代收款业务ID,需通过签约ID查出所有代收款记录,再去匹配是否存在已发起或已处理流程
			NeedReceiveRefundDto nrrDto = new NeedReceiveRefundDto();
			nrrDto.setRelationId(signedId);
			nrrDto.setBusinessType(BusinessTypeEnum.SIGNED.getNo());
			nrrDto.setDocType(DocTypeEnum.COLLECTION.getNo());
			ResponseList<NeedReceiveRefund> nrrListRes = needReceiveRefundServiceFacade.findByDto(nrrDto);
			if (nrrListRes.isSuccess() && null != nrrListRes.getEntity() && nrrListRes.getEntity().size() > 0) {
				List<NeedReceiveRefund> nrrList = nrrListRes.getEntity();
				// 判断所有代收中有没有存在审核中的记录
				boolean flagAudit = false;
				boolean flagComplete = false;
				String tipMsg = "";
				for (NeedReceiveRefund nrr : nrrList) {
					BusinessAbnormaDto businessAbnormaDto = new BusinessAbnormaDto();
					businessAbnormaDto.setBusinessId(nrr.getId());
					businessAbnormaDto.setBusinessType(BusinessAbnormaEnum.BusinessAbnorma_12.getNo());
					// 审核条件去掉,根据状态判断
					// 1、待提交: 无暂存功能,不存在待提交延期收款审批
					// 2、审核中: 存在未审核完成记录,不允许发起
					// 3、已退回: 退回后,无法再次发起
					// 4、已通过: 已通过,再次提醒是否需要再次发起
					businessAbnormaDto.setOrders("create_time desc");
					ResponseList<BusinessAbnorma> businessAbnormas = businessAbnormaServiceFacade
							.findByDto(businessAbnormaDto);
					if (businessAbnormas.isSuccess() && null != businessAbnormas.getEntity()
							&& businessAbnormas.getEntity().size() != 0) {
						List<BusinessAbnorma> baList = businessAbnormas.getEntity();
						BusinessAbnorma ba = baList.get(0);
						String auditStatus = ba.getAuditStatus();
						if (AuditStatusEnum.AUDIT.getNo().equals(auditStatus)) {
							flagAudit = true;
							break;
						} else if (AuditStatusEnum.SUCCESS.getNo().equals(auditStatus)
								|| AuditStatusEnum.REJECT.getNo().equals(auditStatus)) {
							flagComplete = true;
							tipMsg += nrr.getReceivablesFunds() + ": "
									+ DateUtils.DateToString(ba.getCheckDate(), "yyyy年MM月dd日") + "<br />";
						}
					}
				}
				if (flagAudit) {
					// 存在审核中延期审核,返回值定义为1
					ar.setResMsg("1");
				} else if (flagComplete) {
					// 存在已通过延期审核,返回值定义为2
					ar.setResMsg("2");
					ar.setObj(tipMsg);
				}
			}
		} catch (Exception e) {
			logger.error(e.toString(), e);
			ar.setRes(Const.FAIL);
			ar.setFailMsg(Const.DATA_FAIL);
		}
		return ar;
	}

	// 保存延期收款批单
	@RequestMapping(value = "submitDeferredPayment")
	public @ResponseBody AjaxRes submitDeferredPayment(Long signedId, Long needReceiveRefundId, String remark,
			String delayDate, String fileUrlArr, String imageType) {
		AjaxRes ar = getAjaxRes();
		Response<NeedReceiveRefund> needReceiveRefundResponse = new Response<NeedReceiveRefund>();
		User user = ShiroUtil.getCurrentUser();
		try {
			needReceiveRefundResponse = needReceiveRefundServiceFacade.findById(needReceiveRefundId);
			if (!needReceiveRefundResponse.isSuccess() || null == needReceiveRefundResponse.getEntity()) {
				ar.setFailMsg(Const.SAVE_FAIL);
				return ar;
			}

			Response<Signed> signedResponse = signedServiceFacade.findById(signedId);
			if (!signedResponse.isSuccess() || null == signedResponse.getEntity()) {
				ar.setFailMsg(Const.SAVE_FAIL);
				return ar;
			}
			Long projectId = signedResponse.getEntity().getProjectId();
			if (null == projectId) {
				ar.setFailMsg("项目不存在!");
				return ar;
			}
			// 是否存在审核中的延期签约记录，如果存在，则不能再次发起
			BusinessAbnormaDto queryDto = new BusinessAbnormaDto();
			queryDto.setBusinessId(needReceiveRefundId);
			queryDto.setBusinessType(BusinessAbnormaEnum.BusinessAbnorma_12.getNo());
			ResponseList<BusinessAbnorma> responseList = businessAbnormaServiceFacade.findByDto(queryDto);
			boolean isSubmit = true;
			if (responseList.isSuccess() && null != responseList.getEntity()) {
				List<BusinessAbnorma> abList = responseList.getEntity();
				for (BusinessAbnorma ab : abList) {
					String auditStatus = ab.getAuditStatus();
					if (auditStatus.equals(AuditStatusEnum.AUDIT.getNo())
							|| auditStatus.equals(AuditStatusEnum.TOSUBMIT.getNo())) {
						isSubmit = false;
						break;
					}
				}
			}
			if (!isSubmit) {
				ar.setFailMsg("存在审核中延期收款记录，不能重复发起");
				return ar;
			}

			Date conversionSignDate = needReceiveRefundResponse.getEntity().getReceivablesDate();
			BusinessAbnormaDto dto = new BusinessAbnormaDto();
			dto.setBusinessId(needReceiveRefundId);
			dto.setDelaydate(com.emm.yixun.common.utils.DateUtils.StringToDate(delayDate, DateStyle.YYYY_MM_DD));
			dto.setConversionSignDate(conversionSignDate);
			dto.setBusinessType(BusinessAbnormaEnum.BusinessAbnorma_12.getNo());
			dto.setAuditStatus(AuditStatusEnum.TOSUBMIT.getNo());
			dto.setRemark(remark);
			dto.setMerchantId(user.getMerchantId());
			dto.setCreateUserId(user.getId());
			dto.setDelFlag("0");
			dto.setUpdateUserId(user.getId());
			dto.setUpdateTime(new Date());
			dto.setUserCode(user.getUserCode());
			dto.setAccessCode(signedResponse.getEntity().getAccessCode());
			Long delayDays = com.emm.yixun.common.utils.DateUtils.getDaysSub(conversionSignDate, dto.getDelaydate());
			if (delayDays <= 0) {
				ar.setFailMsg("延期收款日期不能在应收款日期之前");
				return ar;
			}
			String processDefinitionKey = "";
			// 判断商户是绿城还是丰策
			if (MerchantEnum.FENGCE.getNo().equals(String.valueOf(user.getMerchantId()))) {
				String startProcessKey = activitiProcessService.getProcessKey(user.getMerchantId(), projectId,
						ProcessTypeEnums.PROCESS_KEY_18);
				if (StringUtils.isEmpty(startProcessKey)) {
					ar.setFailMsg("项目未设置延期签约审批流程,请去项目流程菜单配置！");
					return ar;
				}
				processDefinitionKey = startProcessKey;
			} else {
				if (0 < delayDays && delayDays <= 15) {
					String startProcessKey = activitiProcessService.getProcessKey(user.getMerchantId(), projectId,
							ProcessTypeEnums.PROCESS_KEY_18);
					if (StringUtils.isEmpty(startProcessKey)) {
						ar.setFailMsg("项目未设置延期收款审批流程,请去项目流程菜单配置！");
						return ar;
					}
					processDefinitionKey = startProcessKey;
				} else if (15 < delayDays && delayDays <= 30) {
					String startProcessKey = activitiProcessService.getProcessKey(user.getMerchantId(), projectId,
							ProcessTypeEnums.PROCESS_KEY_19);
					if (StringUtils.isEmpty(startProcessKey)) {
						ar.setFailMsg("项目未设置延期收款审批流程,请去项目流程菜单配置！");
						return ar;
					}
					processDefinitionKey = startProcessKey;
				} else if (delayDays > 30) {
					String startProcessKey = activitiProcessService.getProcessKey(user.getMerchantId(), projectId,
							ProcessTypeEnums.PROCESS_KEY_20);
					if (StringUtils.isEmpty(startProcessKey)) {
						ar.setFailMsg("项目未设置延期收款审批流程,请去项目流程菜单配置！");
						return ar;
					}
					processDefinitionKey = startProcessKey;
				}
			}
			boolean isSeting = activitiProcessService.checkNodeUser(user.getMerchantId(), projectId,
					processDefinitionKey);
			if (!isSeting) {
				ar.setFailMsg("延期收款审批流程节点人员未设置");
				return ar;
			}
			Response<BusinessAbnormaDto> response = businessAbnormaServiceFacade.save(dto);
			if (response.isSuccess()) {
				// 启动流程
				Map<String, Object> variables = new HashMap<String, Object>();
				variables.put("delayDays", delayDays);
				identityService.setAuthenticatedUserId(user.getUserAccount());
				String pid = activitiProcessService.startProcessInstance(user.getMerchantId(), projectId,
						processDefinitionKey, response.getEntity().getId().toString(), variables);
				// 更新审批状态
				BusinessAbnormaDto updateDto = new BusinessAbnormaDto();
				updateDto.setId(response.getEntity().getId());
				updateDto.setAuditStatus(AuditStatusEnum.AUDIT.getNo());
				updateDto.setProcInstId(pid);
				updateDto.setCheckDate(new Date());
				businessAbnormaServiceFacade.updateByPrimaryKey(updateDto, true);
				// 保存流程附件
				if (StringUtils.isNotBlank(fileUrlArr)) {
					wsImageService.uploadAttachment(fileUrlArr, String.valueOf(response.getEntity().getId()), imageType,
							response.getEntity().getAccessCode());
				}
				ar.setSucceed(response.getEntity().getId());
			} else {
				ar.setFailMsg(Const.SAVE_FAIL);
			}
		} catch (Exception ex) {
			//新增业务操作异常记录
			businessLogServiceFacade.saveExceptionLog(user, "新增签约延期收款", JSONObject.toJSONString(needReceiveRefundResponse), JSONObject.toJSONString(ex));
			
			logger.error("新增签约延期收款", ex);
			ar.setFailMsg(Const.SAVE_FAIL);
		}
		return ar;
	}

	// 分页查询
	@RequestMapping(value = "getPageDtoByCustomerId", method = RequestMethod.POST)
	@ResponseBody
	public Page<SignedDto> getPageDtoByCustomerId(String customerId, Integer limit, Integer page) {
		/*
		 * 1.判断权限2.调用分页查询接口3.返回信息
		 */
		if (doSecurityIntercept(Const.RESOURCES_TYPE_BUTTON, "marketing:signed:list")) {
			try {
				if(StringUtils.isBlank(customerId)) {
					return new Page<SignedDto>();
				}
				Response<Page<SignedDto>> response = signedService.getPageDtoByCustomerId(customerId, limit, page);
				if (response.isSuccess()) {
					Page<SignedDto> pages = response.getEntity();
					pages.setPageNumber(page);
					return pages;
				} else {
				}
			} catch (Exception e) {
				logger.error(e.toString(), e);
			}
		}
		return new Page<SignedDto>();
	}

	@RequestMapping(value="toSignedInfoList")
	public String toCustomerInfoList(ModelMap map){
		map.put("permitBtn", doSecurityIntercept(Const.RESOURCES_TYPE_BUTTON, "signed:list:all"));
		ProjectPremisesDto premisesDto = new ProjectPremisesDto();
		premisesDto.setProjectId(153l);
		ResponseList<ProjectPremises> dataList = projectPremisesServiceFacade.findByDto(premisesDto);
		map.put("premisesList",dataList.getEntity());
		return "/customer/signed/signedInfoList";
	}


	/**
	 * 查询签约明细
	 * @param request
	 * @return
	 */
	@RequestMapping(value="signdInfoList", method=RequestMethod.POST)
	@ResponseBody
	public AjaxRes signdInfoList(HttpServletRequest request, Integer pageSize,Integer pageNum){
		AjaxRes ar=getAjaxRes();
		try {
			//获取用户
			User user = ShiroUtil.getCurrentUser();
			if(user == null){
				ar.setFailMsg(Const.SAVE_FAIL);
				return ar;
			}
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			SimpleDateFormat sdfEX = new SimpleDateFormat("yyyy-MM-dd");
			String premisesId = request.getParameter("premisesId");
			String strTime =   request.getParameter("strTime");
			String endTime =   request.getParameter("endTime");

			SignedDto dto = new SignedDto();
			dto.setPremisesId(premisesId);
			if (strTime != "" && strTime != null){
				dto.setStrTime(sdf.parse(strTime+" 00:00:00"));
			}
			if (endTime != "" && endTime != null){
				dto.setEndTime(sdf.parse(endTime+" 23:59:59"));
			}
			Page<SignedDto> page = signedServiceFacade.getSignedInfoPage(dto,PageUtil.begin(pageNum, pageSize), pageSize);
			if(page.getSuccess()){
				if(null==page.getRows()) {
					page.setRows(new ArrayList<SignedDto>());
				}else{
					for(SignedDto c : page.getRows()){
						String signDate = "";
						String handoverDate="";
						String didTime = "";
						String attributionDate = "";
						String projectType = "";
						if(c.getSignDate() != null){
							signDate = sdfEX.format(c.getSignDate());
							c.setSignDateStr(signDate);
						}else{
							c.setSignDateStr(signDate);
						}
						if (c.getCheckDate() != null){
							didTime = sdfEX.format(c.getCheckDate());
							c.setDidTimeStr(didTime);
						} else if(c.getCheckDate() == null){
							didTime = sdfEX.format(c.getDidTime());
							c.setDidTimeStr(didTime);
						}else{
							c.setDidTimeStr(didTime);
						}
						if (c.getHandoverDate() != null){
							handoverDate = sdfEX.format(c.getHandoverDate());
							c.setHandoverDateStr(handoverDate);
						}else{
							c.setHandoverDateStr(handoverDate);
						}
						if(c.getAttributionDate() != null){
							attributionDate = sdfEX.format(c.getAttributionDate());
							c.setAttributionDateStr(attributionDate);
						}else{
							c.setAttributionDateStr(attributionDate);
						}
//						if (c.getPropertyType() != null && c.getPropertyType() != ""){
//							projectType = ProjectTypeEnum.getByNo(c.getPropertyType()).getDes();
//							c.setProjectType(projectType);
//						}else{
//							c.setProjectType(projectType);
//						}
						if(c.getPaymentMethod() != null){
							// 付款方式
							PaymentMethodEnum paymentMethodEnum = PaymentMethodEnum.getByNo(c.getPaymentMethod());
							c.setPaymentMethod(paymentMethodEnum.getDes());
						}
						if(c.getContactType().equals("1")){
							c.setContactType("网签");
						}
						if(c.getContactType().equals("2")){
							c.setContactType("草签");
						}
						if(c.getDepositReceivable() == null){
							c.setDepositReceivable(new BigDecimal("0.00"));
						}
						if (c.getShoufuAmount() == null){
							c.setShoufuAmount("");
						}
						if(c.getYinhangAmount() == null){
							c.setYinhangAmount("");
						}
						if(c.getDocumentNumber() != null){
							c.setPeDocumentNumber(c.getPeDocumentNumber()+","+c.getDocumentNumber());
						}
						if(c.getMobile() != null){
							c.setCustomerPhone(c.getCustomerPhone()+","+c.getMobile());
						}
						if(c.getMemberName() != null){
							c.setCustomerName(c.getCustomerName()+","+c.getMemberName());
						}
						if(c.getShoufu() > 0){
							c.setShoufuStr("是");
						}else{
							c.setShoufuStr("否");
						}
						if(c.getDiscountNote() != null){
							c.setDiscountNote(c.getDiscountNote());
						}else{
							c.setDiscountNote("");
						}
					}

				}

			}else{
				ar.setFailMsg(Const.DATA_FAIL);
			}
			page.setPageNumber(pageNum);
			ar.setSucceed(page);
		} catch (Exception e) {
			logger.error(e.toString(),e);
			ar.setFailMsg(Const.DATA_FAIL);
		}
		return ar;
	}


	/**
	 * 导出签约明细列表
	 * @param request
	 * @return
	 */
	@RequestMapping("exportSignedInfoList")
	@ResponseBody
	public AjaxRes exportCustomerInfoList(HttpServletRequest request, HttpServletResponse response, Model model) {
		AjaxRes ar=getAjaxRes();
		try {
			//获取用户
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            SimpleDateFormat sdfEX = new SimpleDateFormat("yyyy-MM-dd");
			User user = ShiroUtil.getCurrentUser();
			String premisesId = request.getParameter("premisesId");
			String strTime = request.getParameter("strTime");
            String endTime = request.getParameter("endTime");

			SignedDto dto = new SignedDto();
			dto.setPremisesId(premisesId);
			if(strTime != null && strTime != ""){
				dto.setStrTime(sdf.parse(strTime+" 00:00:00"));
            }
			if(endTime != null && endTime != ""){
				dto.setEndTime(sdf.parse(endTime+" 23:59:59"));
            }
			ResponseList<SignedDto> resultList = signedServiceFacade.getSignedInfoByDto(dto);
			//设置excel sheet
			String[] name = {"签约信息明细列表"};
			//设置excel 列表表头
			List<String[]> headerList = new ArrayList<String[]>();
			String[] header = {
					"合同签署日期", "合同编号", "订房日期", "交房日期","房间","产品类型","客户姓名",
					"证件号","联系电话","联系地址","成交面积","标准单价","标准总价","成交单价",
					"成交总价","付款方式","是否首付分期","按揭金额","最终折扣","折扣说明","应收首付款","已交金额","置业顾问","合同类别","业务归属日期"
			};
			headerList.add(header);

			List<String[]> headerNumList = new ArrayList<String[]>();
			String[] headerNum = new String[]{

					"成交面积","标准单价","标准总价","成交单价","成交总价","按揭金额","最终折扣","应收首付款"
					,"已交金额"

			};
			headerNumList.add(headerNum);
			//组装数据
			List<List<Map<String, String>>> list = new ArrayList<List<Map<String, String>>>(); //数据集合
			List<Map<String, String>> listMap = buildCustomerInfoList(resultList.getEntity(), header);
			list.add(listMap);
			ExcelUtil.exportExcelForNumber(list, headerList,headerNumList, name, response);
			ar.setSucceedMsg(Const.SAVE_SUCCEED);
		} catch (Exception e) {
			logger.error("导出逾期未签约列表失败", e);
			ar.setFailMsg(Const.DATA_FAIL);
		}
		return ar;
	}


	/**
	 * 组装导出逾期未签约数据
	 */
	private List<Map<String, String>> buildCustomerInfoList(List<SignedDto> list, String[] head) {
		List<Map<String, String>> listMap = new ArrayList<Map<String,String>>();
		try {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
			for (int i=0;i<list.size();i++) {
				SignedDto data = list.get(i);
				Map<String, String> map = new HashMap<String, String>();
				if(data.getSignDate() != null ){
                    map.put(head[0]+"_"+i, sdf.format(data.getSignDate())); //签约日期
                }else{
                    map.put(head[0]+"_"+i, ""); //签约日期
                }

				map.put(head[1]+"_"+i, data.getSignCode()); //合同编号
                if(data.getCheckDate() != null ){
                    map.put(head[2]+"_"+i, sdf.format(data.getCheckDate())); //签约日期
                }else if(data.getCheckDate() == null){
					map.put(head[2]+"_"+i, sdf.format(data.getDidTime())); //签约日期
				}else{
                    map.put(head[2]+"_"+i,""); //签约日期
                }
                if(data.getHandoverDate() != null ){
                    map.put(head[3]+"_"+i, sdf.format(data.getHandoverDate())); //交房日期
                }else{
                    map.put(head[3]+"_"+i, ""); //交房日期
                }

				map.put(head[4]+"_"+i, data.getCombinedName());
                if(data.getCodeName() != null  && data.getCodeName() !=""){
                    map.put(head[5]+"_"+i, data.getCodeName());
                }else{
                    map.put(head[5]+"_"+i,"");
                }
                if(data.getMemberName() != null){
					map.put(head[6]+"_"+i, data.getCustomerName()+","+data.getMemberName());
				}else{
					map.put(head[6]+"_"+i, data.getCustomerName());
				}
				if(data.getDocumentNumber() != null){
					map.put(head[7]+"_"+i, data.getPeDocumentNumber()+","+data.getDocumentNumber());
				}else{
					map.put(head[7]+"_"+i, data.getPeDocumentNumber());
				}
				if(data.getMobile() != null){
					map.put(head[8]+"_"+i, data.getCustomerPhone()+","+data.getMobile());
				}else{
					map.put(head[8]+"_"+i, data.getCustomerPhone());
				}
				map.put(head[9]+"_"+i, data.getPeContactAddress());

                if(data.getCalculateArea() != null){
                    map.put(head[10]+"_"+i,data.getCalculateArea().toString());
                }else{
                    map.put(head[10]+"_"+i,"");
                }

				if(data.getConversionPrice() != null){
					map.put(head[11]+"_"+i,data.getConversionPrice().toString());
				}else{
					map.put(head[11]+"_"+i,"");
				}
                if(data.getLumpsumPrice() != null){
                    map.put(head[12]+"_"+i, data.getLumpsumPrice().toString());
                }else{
                    map.put(head[12]+"_"+i,"");
                }

                if(data.getSignPrice() != null){
                    map.put(head[13]+"_"+i, data.getSignPrice().toString());
                }else{
                    map.put(head[13]+"_"+i,"");
                }

				if(data.getSignAmount() != null){
					map.put(head[14]+"_"+i, data.getSignAmount().toString());
				}else{
					map.put(head[14]+"_"+i,"");
				}

                if(data.getPaymentMethod() != null  && data.getPaymentMethod() !=""){
                    map.put(head[15]+"_"+i, PaymentMethodEnum.getByNo(data.getPaymentMethod()).getDes());
                }else{
                    map.put(head[15]+"_"+i, "");
                }

                if(data.getShoufu() > 0){
					map.put(head[16]+"_"+i, "是");
				}else{
					map.put(head[16]+"_"+i, "否");
				}

				map.put(head[17]+"_"+i, data.getYinhangAmount());//按揭金额
                if(data.getDiscountAmount() != null ){
                    map.put(head[18]+"_"+i, data.getDiscountAmount().toString());
                }else{
                    map.put(head[18]+"_"+i, "");
                }

				map.put(head[19]+"_"+i, data.getDiscountNote());

				map.put(head[20]+"_"+i, data.getShoufuAmount());//应收首付款
//                if(data.getDiscountAmount() != null ){
//                    map.put(head[19]+"_"+i, data.getDiscountAmount().toString());
//                }else{
//                    map.put(head[19]+"_"+i, "");
//                }

                if(data.getDepositReceivable() != null ){
                    map.put(head[21]+"_"+i, data.getDepositReceivable().toString());//已交定金
                }else{
                    map.put(head[21]+"_"+i, "");
                }


				map.put(head[22]+"_"+i, data.getUserName());
				if(data.getContactType().equals("1")){
					map.put(head[23]+"_"+i, "网签");
				}
				if(data.getContactType().equals("2")){
					map.put(head[23]+"_"+i, "草签");
				}
                if(data.getAttributionDate() != null ){
                    map.put(head[24]+"_"+i, sdf.format(data.getAttributionDate()));
                }else{
                    map.put(head[24]+"_"+i, "");
                }

				listMap.add(map);
			}
		} catch (Exception e) {
			logger.error("组装导出签约回款提醒数据错误：{}",e);
		}
		return listMap;
	}

}
